当我们通过实现Runnable并将其传递给Thread构造函数来实现相同的功能时,允许用户通过扩展Thread类来创建线程的本质是什么。
答案 0 :(得分:3)
通过实现相同的功能 实现Runnable并将其传递给 线程构造函数
扩展Thread的使用不仅限于Runnable。例如,您可以change the behavior of some methods或添加自己的线程本地信息(始终可以Thread.currentThread()
访问)。
答案 1 :(得分:3)
从历史角度来看,您需要了解在Java支持的匿名内部类之前,Thread
API是在Java 1.0中设计的。许多早期的示例代码显示了Thread
的子类化。直到后来:
Runnable
实例很好地说“.Net中的Thread类标记为最终版”,但是你必须意识到C#/ .Net在几年之后就出现了...而且能够从Java的设计中学习。 Java被许多不太完美的设计决策的历史包袱所困扰......因为最重要的是不要破坏旧代码。
答案 2 :(得分:2)
Thread
很不寻常,因为它可以引用Runnable
来运行,但它本身也是Runnable
。默认情况下,Thread
将自己用作要运行的Runnable
实例,但当然您可以将其指向其他位置。
我认为没有充分的理由要么标记Thread
最终要求外部Runnable
或要求Thread
可扩展并让它成为自己的Runnable
。这两种方法都很完美,似乎没有一种方法比另一方更好。
如果我不得不猜测,使Thread
子类化的原因是它允许你编写这样的代码:
Thread t = new Thread() {
public void run() {
/* ... your code here ... */
}
};
这比创建Runnable
的子类然后将其包装在一个线程中要简单得多。类似地,您可以继承Thread
以获得Runnable
,以清楚地表明它应该用作线程。当然,这主要是一个美学问题,让Java设计师走了另一条路,我认为这将是一个非常好的决定。
答案 3 :(得分:0)
如果我添加一些东西,通过扩展Thread
,您可以拥有一个线程的扩展功能(Runnable
中不存在,因为它只包含run()
方法)允许您的线程充当守护程序线程(就像垃圾收集器守护程序线程一样)。其他线程就像单个非守护程序线程一样,它调用类的 main 方法(当JVM启动时)。
Runnable
接口允许您的类作为线程变为活动状态(通过实现run()
方法)。
答案 4 :(得分:0)
线程类描述了线程的运行方式,Runnable描述了运行的内容。如果要修改运行的内容,则应实现Runnable。如果要修改线程的运行方式,则从Thread派生。在您想要修改线程运行方式的情况下,您可以从Thread派生并实现一个单独的Runnable对象。
答案 5 :(得分:0)
我唯一能想到的好处是:如果你扩展Thread类,它会让你的run()方法被标记为protected。实现Runnable 的一个缺点是你的run方法必须标记为public。