我知道在java中有两种使用线程的方法:
- 实现可运行
- 扩展线程
我也知道实现 Runable比扩展 Thread更好。
但是为什么有两种方法——为什么不只有一种呢?
如果实现Runnable是一种更好的方法,为什么还有另一种选择?
只有一种选择会有什么问题?
我知道在java中有两种使用线程的方法:
我也知道实现 Runable比扩展 Thread更好。
但是为什么有两种方法——为什么不只有一种呢?
如果实现Runnable是一种更好的方法,为什么还有另一种选择?
只有一种选择会有什么问题?
extends Thread
:
您的线程创建唯一对象并与之关联
implements Runnable
:
它与多个线程共享同一个对象
需要注意的另一件事是,由于您只能在 Java 中扩展一个类,如果您extends Thread
是 ,则不能扩展另一个类。如果您选择implement Runnable
,那么您可以扩展课程。
从技术上讲,只有一种方法:实施Runnable
. Thread
,顺便说一句,就是这样做的,所以扩展它你很容易满足接口要求。
这只是我们使用每种类型线程的另一个原因。
扩展Thread
类不会为您提供扩展任何其他类的选项。但是如果你实现Runnable
接口,你可以在你的类中扩展其他类..
因此,根据您的设计要求,您可以使用任何一种方法。
如果您愿意,子类Thread
化类允许您修改该类的其他可覆盖函数。Thread
你,可能,不应该。
此外,子类化 Thread 类有时会产生更具可读性的代码,在您的子类中,您可以拥有自己的自定义 API。可以想象诸如 DownloadingThread、RenderingThread 等类扩展 Thread。
使用线程作为任务提供了一种创建和运行并行线程的紧凑方式
new Thread() {
public void run() {
...
}
}.start();
两种方法都有不同的方法。实现 Runnable 接口不会对线程本身进行任何控制。如果我们扩展线程类,那么派生类就不能扩展任何其他基类。
因此,如果用户想要完全控制程序,那么扩展 Thread 类是更好的选择,如果用户想要灵活地扩展其他基类,那么实现可运行接口是一个不错的选择。
即使您实现了 Runnable 接口,您也需要创建线程以让您的任务作为线程运行。实现 Runnable 的明显优势是
扩展 Thread 类只是一种选择,因为它在内部实现了 Runnable,因此您最终会间接实现 Runnable 接口。只是这个类没有做成final,以防止开发者扩展它。正如 Joshua Bloch 在“Effective Java”中提到的那样,通常没有理由扩展 Thread
通过扩展 Thread,每个线程都有一个与之关联的唯一对象,而实现 Runnable 时,许多线程可以共享同一个可运行实例。
大多数时候,我们使用可运行接口。因为这让我们在结构和功能上更加灵活。Java允许接口的多重继承。这个概念在软件设计中被大量使用。
顺便说一句,还有另一个接口叫做 callable。可调用类可以返回类型 V 的值,也可以抛出检查异常。
当我们通过实现 runnable 创建线程时,我们不会在线程创建期间初始化任何值。但是当我们扩展 Thread 类来创建线程时,如果需要,我们可以使用构造函数的优势来初始化一些值,如下所示
public class MyThread extends Thread
{
int aValue;
public Mythread(int aValue)
{
this.aValue = aValue;
}
............................
............................
}
当我们创建线程时,我们可以如下初始化
MyThread t = new MyThread(7);
t.start();
除此之外,由于 java 不支持多重继承,所以如果我们扩展 Thread 类,那么我们就失去了扩展另一个类的机会。因此在这种情况下,可运行接口对于创建线程非常有帮助