6

当我们可以通过实现 Runnable 并将其传递给 Thread 构造函数来实现相同的功能时,允许用户通过扩展 Thread 类来创建线程的本质是什么。

4

6 回答 6

3

从历史的角度来看,您需要了解ThreadAPI 是在 Java 1.0 中设计的,在 Java 支持匿名内部类之前。很多早期的示例代码都显示了Thread. 直到后来:

  • 他们增加了对匿名内部类的支持(Java 1.1)
  • 他们发现最好使用内部类(等)来提供Runnable实例
  • 他们为任务执行、线程池等(Java 5.0)实现了标准类。

说“.Net 中的 Thread 类被标记为 final”很好,但你必须意识到 C# / .Net 在几年后出现......并且能够从 Java 的设计中学习。Java 曾经/被许多不太完美的设计决策的历史包袱困住了……因为不破坏旧代码的压倒一切的必要性。

于 2011-03-27T00:49:17.730 回答
3

通过实现 Runnable 实现相同的功能并将其传递给 Thread 构造函数

扩展 Thread 的使用不仅限于 Runnable。例如,您可以更改某些方法的行为或添加您自己的线程本地信息(始终使用 访问Thread.currentThread())。

于 2011-03-26T22:35:12.193 回答
2

Thread不寻常之处在于它可以引用Runnableto run,但它本身也是Runnable. 默认情况下,Thread将使用自己作为Runnable实例来运行,当然你可以将它指向其他地方。

我认为这不是标记Threadfinal 并需要 externalRunnable或使其Thread可扩展并拥有它自己的Runnable. 这两种方法都非常好,而且似乎都不是比另一种更好的选择。

如果我不得不猜测,使Thread子类化的原因是它允许您编写如下代码:

Thread t = new Thread() {
    public void run() {
       /* ... your code here ... */
    }
};

这比创建一个子类Runnable然后将其包装在一个线程中要干净一些。类似地,您可以对 of 进行子类化Thread以获得Runnable明确表明它应该用作线程的 a。当然,这主要是一个美学问题,如果 Java 设计者采取相反的方式,我认为这将是一个非常好的决定。

于 2011-03-26T22:16:26.067 回答
0

线程类描述线程如何运行,Runnable 描述运行什么。如果要修改运行的内容,则应实现 Runnable。如果你想修改线程的运行方式,你可以从 Thread 派生。如果您想修改线程的运行方式,您可以从 Thread 派生并实现一个单独的 Runnable 对象。

于 2011-03-27T01:48:54.963 回答
0

如果我可以添加一些东西,通过扩展Thread你可以拥有线程的扩展功能(它不存在,Runnable因为它只包含run()方法),比如允许你的线程充当守护线程(就像垃圾收集器守护线程一样) . 其他线程存在,例如调用类的main方法的单个非守护线程(当 JVM 启动时)。

Runnable接口允许您的类作为线程激活(通过实现run()方法)。

于 2011-03-26T23:02:32.723 回答
0

我能想到的唯一好处是:如果你扩展 Thread 类,它会让你的 run() 方法被标记为受保护。实现 Runnable的一个缺点是你的 run 方法必须被标记为 public。

于 2012-03-20T20:21:47.797 回答