如何启动匿名线程类

时间:2012-03-08 21:21:58

标签: java multithreading anonymous-class

我有以下代码段:

public class A {
    public static void main(String[] arg) {
        new Thread() {
            public void run() {
                System.out.println("blah");
            }
        };
    }
}

这里,如何在不创建线程类实例的情况下为线程调用start()方法?

9 个答案:

答案 0 :(得分:135)

您已经在创建Thread类的实例了 - 您只是没有对它做任何事情。您可以调用start(),甚至不使用本地变量:

new Thread()
{
    public void run() {
        System.out.println("blah");
    }
}.start();

...但我个人通常会将它分配给一个局部变量,做你想做的任何其他事情(例如设置名称等),然后启动它:

Thread t = new Thread() {
    public void run() {
        System.out.println("blah");
    }
};
t.start();

答案 1 :(得分:14)

由于匿名类扩展了给定的类,因此可以将它们存储在变量中。

例如

Thread t = new Thread()
{
    public void run() {
        System.out.println("blah");
    }
};
t.start();

或者,您可以在您立即创建的对象上调用start方法。

new Thread()
{
    public void run() {
        System.out.println("blah");
    }
}.start();
// similar to new Thread().start();

虽然就个人而言,我总是建议创建一个Runnable而不是Thread的匿名实例,因为编译器会警告你,如果你不小心弄错了方法签名(对于匿名类,它会警告你,无论如何我认为,因为匿名类可以不要定义新的非私有方法。

例如

new Thread(new Runnable()
{
    @Override
    public void run() {
        System.out.println("blah");
    }
}).start();

答案 2 :(得分:6)

不完全确定这是你问的问题,但你可以这样做:

new Thread() {
    public void run() {
        System.out.println("blah");
    }
}.start();

注意匿名类末尾的start()方法。您创建了线程对象,但是您需要启动它以实际获得另一个正在运行的线程。

比创建匿名Thread类更好的是创建一个匿名的Runnable类:

new Thread(new Runnable() {
    public void run() {
        System.out.println("blah");
    }
}).start();

而是覆盖run()中的Thread方法,注入要由新线程运行的目标Runnable。这是一个更好的模式。

答案 3 :(得分:3)

只需调用start()

即可
new Thread()
{
    public void run() {
        System.out.println("blah");
    }
}.start();

答案 4 :(得分:3)

整个new表达式是一个对象引用,因此可以在其上调用方法:

public class A {
    public static void main(String[] arg)
    {
        new Thread()
        {
            public void run() {
                System.out.println("blah");
            }
        }.start();
    }
}

答案 5 :(得分:2)

添加:现在您可以使用lambda来简化语法。要求:Java 8 +

public class A {
    public static void main(String[] arg)
    {
        Thread th = new Thread(() -> {System.out.println("blah");});
        th.start();
    }
}

答案 6 :(得分:0)

我很惊讶我没有看到Java的Executor框架提到这个问题的答案。 Executor框架的主要卖点之一是你没有处理低级线程。相反,你正在处理https://slack.botframework.com/api/Events/(bothandle)的更高层次的抽象。因此,不要手动启动线程,只需执行包装Runnable的执行程序。使用单线程执行程序,您创建的Integer实例将在内部被包装并作为线程执行。

Runnable

为方便起见,请参阅ExecutorService

答案 7 :(得分:0)

将此留在这里供将来参考,但也是一个答案。

new Thread(() - > whatever())。start();

答案 8 :(得分:0)

创建匿名类的另一个方便的技巧,该类扩展了 Thread 类,而不仅仅是将 Runnable 实例或 lambda 传递给 Thread 类的构造函数:

  // This also starts the new thread when instantiating the Anonymous class
  // By invoking "this.start()" in a instance initializer block of the Anonymous Thread.
  // Note: We can also override the run from the Thread class itself instead if providing external runnable just in case.
  Thread t = new Thread(()->{}){{start();}};
  
  Runnable r1 = ()->{}; // Runnable Functional Interface lambda format  
  Thread t1 = new Thread(r1){{start();}};

  // Anonymous class which implements Runnable interface
  Runnable r2 = new Runnable(){
    @Override
    public void run(){
      //do some work 
    }
  }
  Thread t2 = new Thread(r2){{start();}};

  // Anonymous class which extends Thread class
  Thread t3 = new Thread(){
    {
       start();
    }
    @Override
    public void run(){
      //do some useful work
    }
  }
  
  class ExtendedThread extends Thread{
    ExtendedThread(){this(null);}
    ExtendedThread(Runnable runnable){
       super(runnable);
       start();
    }
    @Override
    public void run(){
      super.run();
      //do some more useful work always even if there was no runnable was passed via constructor
    } 
  }
  
  Thread t3 = new Thread();