从我在Java中使用线程的时间来看,我发现了两种编写线程的方法:

使用可运行的机具:

public class MyRunnable implements Runnable {
    public void run() {
        //Code
    }
}
//Started with a "new Thread(new MyRunnable()).start()" call

或者,使用扩展线程:

public class MyThread extends Thread {
    public MyThread() {
        super("MyThread");
    }
    public void run() {
        //Code
    }
}
//Started with a "new MyThread().start()" call

这两个代码块有什么显著的区别吗?


当前回答

Runnable是一个接口,而Thread是实现该接口的类。从设计的角度来看,任务的定义方式和执行方式之间应该有明确的区分。前者由Runnalbe实现负责,后者由Thread类负责。在大多数情况下,实现Runnable是正确的做法。

其他回答

我想说还有第三种方法:

public class Something {

    public void justAnotherMethod() { ... }

}

new Thread(new Runnable() {
   public void run() {
    instanceOfSomething.justAnotherMethod();
   }
}).start();

也许这受到了我最近大量使用Javascript和Actionscript 3的影响,但是这样你的类就不需要实现一个非常模糊的接口,比如Runnable。

Runnable是一个接口,而Thread是实现该接口的类。从设计的角度来看,任务的定义方式和执行方式之间应该有明确的区分。前者由Runnalbe实现负责,后者由Thread类负责。在大多数情况下,实现Runnable是正确的做法。

对如果调用ThreadA调用,则不需要调用start方法,run方法只在调用ThreadA类后调用。但如果使用ThreadB调用,则需要启动线程来调用run方法。如果你还有什么帮助,请回复我。

如果我没有错的话,它或多或少类似于

接口和抽象类之间的区别是什么?

extends建立“Is A”关系,接口提供“Has A”功能。

首选工具可运行:

如果不需要扩展Thread类并修改Thread API默认实现如果你执行的是一个火灾和忘记命令如果您已经在扩展另一个类

首选“扩展线程”:

如果必须重写oracle文档页中列出的任何线程方法

通常,您不需要重写线程行为。因此,在大多数情况下,首选实现Runnable。

另一方面,使用高级ExecutorService或ThreadPoolExecutorServiceAPI提供了更多的灵活性和控制。

看看这个SE问题:

ExecutorService vs休闲线程生成器

Java不支持多重继承,所以如果您扩展Thread类,则不会扩展其他类。

例如:如果您创建一个applet,那么它必须扩展applet类,所以这里创建线程的唯一方法是实现Runnable接口