从我在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,则可以节省空间以扩展到任何其他类。

其他回答

我们可以重新访问我们希望我们的类表现为线程的基本原因吗?根本没有理由,我们只是想执行一个任务,最有可能是在异步模式下,这恰恰意味着任务的执行必须从我们的主线程和主线程分支,如果提前完成,可能会或可能不会等待分支路径(任务)。

如果这就是全部目的,那么我在哪里看到需要专门的线程。这可以通过从系统的线程池中提取一个RAW线程并分配给它我们的任务(可能是我们类的一个实例)来完成,就是这样。

因此,让我们遵循OOP概念,编写一个所需类型的类。做事有很多方法,用正确的方式做事很重要。

我们需要一个任务,所以写一个可以在线程上运行的任务定义。所以使用Runnable。

始终记住,机具专门用于传递行为,扩展用于传递特性/属性。

我们不希望线程的属性,而是希望我们的类作为一个可以运行的任务。

扩展线程与实现可运行线程之间的区别在于:

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

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

实现Runnable和扩展Thread之间的一个区别是,通过扩展Thread,每个线程都有一个与其关联的唯一对象,而实现Runnable,许多线程可以共享同一个对象实例。

实现Runnable的类不是线程,只是一个类。对于要由线程执行的Runnable,需要创建一个Thread实例,并将Runnable实例作为目标传入。

在大多数情况下,如果只打算重写run()方法而不打算重写其他Thread方法,则应使用Runnable接口。这一点很重要,因为除非程序员打算修改或增强类的基本行为,否则类不应该被子类化。

当需要扩展超类时,实现Runnable接口比使用Thread类更合适。因为我们可以在实现Runnable接口时扩展另一个类以生成线程。但是如果我们只是扩展Thread类,我们就不能从任何其他类继承。