从我在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使您的类更加灵活。

如果你扩展了线程,那么你正在做的动作总是在一个线程中。然而,如果你实现了Runnable,那就不必了。你可以在一个线程中运行它,或者将它传递给某种类型的执行器服务,或者将其作为一个任务在一个单线程应用程序中传递(可能稍后运行,但在同一个线程内)。如果只使用Runnable,则选项比将自己绑定到Thread时开放得多。

其他回答

实例化接口在代码和线程的实现之间提供了更清晰的分离,因此在这种情况下我更希望实现Runnable。

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

简单的说法是:如果你实现了接口,这意味着你正在实现它的所有方法,如果你扩展了类,你正在继承你选择的方法。。。在这种情况下,只有一个名为Run()的方法,因此更好地实现Runnable接口。。

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

如果你想分开你的关注点,比如,如果你想创建任务,而谁是处理你任务的工作人员对你来说无关紧要,那么使用Runnable并将你的工作定义为任务。就像使用executor服务一样,您以Runnable/callable的形式定义任务,并将它们交给executor,然后由executor负责。

如果您想自己创建一个工作线程并将任务分配给该工作线程,那么您需要对工作线程进行更多的控制,然后使用thread类。