当前位置: 首页 > 知识库问答 >
问题:

通过注释性内部类创建线程

欧阳飞
2023-03-14

我正在开发创建线程的代码,但没有扩展thread类或实现runnable接口,即通过匿名内部类。。

public class Mythread3 {
    public static void main(String... a) {

        Thread th = new Thread() {

            public synchronized void run() {
                for (int i = 0; i < 20; i++) {
                    try {
                        Thread.sleep(1000);

                        System.out.print(i + "\n" + "..");
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }

            }

        };

        th.start();
        Thread y = new Thread();
        y.start();

    }
}

现在请告诉我,我可以用同样的方法创建子线程吗...!!我尝试的是...

public class Mythread3 {
    public static void main(String... a) {

        Thread th = new Thread() {

            public synchronized void run() {
                for (int i = 0; i < 20; i++) {
                    try {
                        Thread.sleep(1000);

                        System.out.print(i + "\n" + "..");
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }

            }

        };

        Thread th1 = new Thread() {

            public synchronized void run() {
                for (int i = 0; i < 20; i++) {
                    try {
                        Thread.sleep(1000);

                        System.out.print(i + "\n" + "..");
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }

            }

        };
        th.start();
        try {
            th.join();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        th1.start();

    }
}

但是其中有两个run()方法,我认为这不实用。。请建议。。!

共有3个答案

祁兴运
2023-03-14

匿名内部类是没有名称的类,这意味着它没有明确的名称,但是JVM将其命名为Mythread31美元以引用其对象。所以当你打印th.getClass()和th.getClass(). getSuperclass()时,你会得到MyThread31美元和线程的输出。

您可以通过扩展Thread类或其任何子类(另一个实现Runnable接口或其任何子类型)来创建匿名内部类。在第一段代码中,您扩展了线程类。这就是为什么您将类名命名为MyThread31美元(因为它是匿名内部类)和超类命名为Thread类(因为您扩展了它)。因此,您可以创建尽可能多的匿名内部类来扩展线程类,JVM将它们命名为MyThread31美元、MyThread32美元、MyThread33美元......但是当您调用start方法时,每个线程将只执行它们的run方法(您通过扩展线程类覆盖了MyThread31美元、MyThread32美元)。

package com.tej.threads;

public class MyThread3 {
public static void main(String... a) {

    Thread th = new Thread() {

        public synchronized void run() {
            for (int i = 0; i < 20; i++) {
                try {

                    System.out.println(i + "\t" + ".." + Thread.currentThread().getId());
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

        }

    };
    Thread th1 = new Thread() {

        public synchronized void run() {
            for (int i = 50; i < 70; i++) {
                try {

                    System.out.println(i + "\t" + ".."+ Thread.currentThread().getId());
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

        }

    };
    th.start();
    try {
        th.join();
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    th1.start();
    System.out.println(th.getClass()+ " " + th.getClass().getSuperclass());
    for(int i=0;i<20;i++)
    {
        System.out.println("i am main Thread");
    }


  }
}

输出为

0   ..8
1   ..8
2   ..8
3   ..8
4   ..8
5   ..8
6   ..8
7   ..8
8   ..8
9   ..8
10  ..8
11  ..8
12  ..8
13  ..8
14  ..8
15  ..8
16  ..8
17  ..8
18  ..8
19  ..8
class com.tej.threads.MyThread3$1 class java.lang.Thread
i am main Thread
i am main Thread
i am main Thread
i am main Thread
i am main Thread
i am main Thread
i am main Thread
i am main Thread
i am main Thread
i am main Thread  
i am main Thread
i am main Thread 
i am main Thread
i am main Thread
i am main Thread
i am main Thread
i am main Thread
i am main Thread
i am main Thread
i am main Thread
50  ..9
51  ..9
52  ..9
53  ..9
54  ..9
55  ..9
56  ..9
57  ..9
58  ..9
59  ..9
60  ..9
61  ..9
62  ..9
63  ..9
64  ..9
65  ..9
66  ..9
67  ..9
68  ..9
69  ..9

您可以清楚地看到thread1将打印1到20的id,Thread2将打印50到70的id,这意味着每个线程正在执行自己的run方法。注意:主线程将逐行执行程序,如果遇到th.start方法,主线程将发送子线程执行其run方法,主线程将转到下一行执行。

罗浩然
2023-03-14

您声明两个匿名内部类扩展Thread并覆盖run()方法这一事实本身并不是问题。我们可能认为不是真正可读的,但没有问题。

但是,您应该考虑使用Runnable接口。您应该将处理/算法和线程策略分开。所以最好有这样的东西:

public class ThreadLauncher {
    public static void main(String[] args) {
         Thread job1 = new Thread(new Job1());
         Thread job2 = new Thread(new Job2());
         job1.start();
         job2.start();
    }
}

public class Job1 implements Runnable {
    @Override
    public void run() {
         // Do some stuff
    }
}

public class Job2 implements Runnable {
    @Override
    public void run() {
         // Do some other stuff
    }
}

例如,这允许您多次启动同一作业。

如果您想更进一步,可以考虑使用ThreadPoolExecutor来处理线程策略。

尉迟龙光
2023-03-14
 Runnable run = new Runnable() {
    public void run() {
        try {
            for (int i = 0; i < 20; i++) {
                Thread.sleep(1000);
                System.out.print(i + "\n" + "..");
            }

        } catch (InterruptedException e) {
            System.out.println(" interrupted");
        }
    }
 };
 new Thread(run).start();
 new Thread(run).start();

不要等到一个线程完成后再开始第二个线程,否则有三个线程在其中一个线程上运行(在这种情况下,额外的线程是没有意义的)

顺便说一句:您的同步没有做任何有用的事情,但它可能会导致线程运行不正确。

 类似资料:
  • 我是Spring Security的新手。我看过很多关于如何通过外部属性文件的注释注入值的文章。我尝试了很多方法,但最终都是用java。lang.IllegalArgumentException:无法解析占位符“val.id”异常。 你能给我一些提示如何处理这个例外吗? 我的java类如下所示: 我的属性文件名为val.properties,位于WEB-INF下,其内容为val.id=xyz 我将

  • 问题内容: 因此,我们具有以下形式的XSD类型: 表示XML: xjc产生几乎正确的结果。唯一令人讨厌的是,“ Bars”被创建为存储Bars列表的内部类。无论如何,在Foo中将Bars列为列表,同时仍保留上面的XML? 问题答案: 另一种方法是删除周围的 元素,XML看起来不再那么漂亮了,但是它将使Java代码更易于阅读。与xjc的简单绑定(请参阅 http://jaxb.java.net/no

  • 我正在尝试将Spring LDAP 池上下文源 XML 配置转换为使用注释。我能够通过遵循此处提到的一个来使 Ldap 上下文源正常工作,但我无法使池上下文源正常工作。当我运行代码时,我得到了空点异常。下面列出了 XML、注释和异常代码段。 XML配置片段, 注释配置片段, 我得到的例外,

  • 问题内容: 有什么方法可以通过JPA注释指定SQL注释?表和列的注释。 问题答案: 有什么方法可以通过JPA注释指定SQL注释?表和列的注释。 否。如果要定义表和列注释,最好的选择是在生成的DDL中根据事实进行操作,然后再对数据库执行操作。

  • 问题内容: 注释如何与Java一起使用?以及如何创建这样的自定义注释: 基本上,我需要保留的POJO在持久化时像这样进行序列化: 这样,实际的生成/持久对象是这样的: 任何想法如何实现这一点? 问题答案: 如果创建自定义注释,则必须使用此处的 API 示例进行处理。您可以参考如何声明注释。 这是Java中的示例注释声明的样子。 并被称为。 表示您想在运行时保留注释,并且可以在运行时访问它。 表示您

  • 问题内容: 我正在尝试使用泛型来实现链接的集合,如下所示。 A是集合,B是集合中的元素或节点,具有引用后继对象/前任对象和项目的数组。 不允许创建数组。我得到的错误是。我认为它实际上创建的是数组吗? 如果不是,是什么原因导致错误? 如果是这样,我该如何解决? 很明显,我省略了很多代码,如果提供的代码不够用,请告诉我。任何意见,将不胜感激。谢谢。 编辑1: 我应该提到的是,参数化类型必须是在同在。因