为什么Java中的java.lang.Thread类没有被设计者标记为final?

时间:2011-03-26 22:08:23

标签: java multithreading language-design runnable library-design

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

6 个答案:

答案 0 :(得分:3)

  

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

扩展Thread的使用不仅限于Runnable。例如,您可以change the behavior of some methods或添加自己的线程本地信息(始终可以Thread.currentThread()访问)。

答案 1 :(得分:3)

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

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

很好地说“.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。