为什么存在'extends Thread',当在所有情况下都应该选择'implements Runnable'? (注意:以上为提问标题,不需要回答)

19
我知道在Java线程中,implements Runnableextends Thread更受推荐,因为它允许我们在需要时扩展其他类。但如果情况是这样的,extends Thread是否也有其自身优势?如果有的话,这些优势是什么?

4
@proudandhonour: 是的,我看过那个问题的答案,但是所有的答案都在解释为什么“implements Runnable”是好的。实际上,这些答案引发了我对这个问题的思考。 - rahul
1
@proudandhonour,您能否提供回答此问题的链接?在前几个答案中好像没有找到。 - djechlin
考虑一种情况,当线程启动时,您需要将该特定线程的详细信息添加到数据库中。这与您在run()方法中拥有的业务逻辑不同,因此您希望将其分开。因此,您将覆盖start()和run()方法。 - akshaya pandey
2个回答

33

有时候(几乎从不,但有时候)您希望能够更改Thread的基本行为。

这就是您需要继承它的时候。

您可以通过覆盖Thread类中的一个方法来更改它,但无法通过实现Runnable中的一个方法来实现。


7
示例 here - 提问者想知道是哪个线程创建/启动了此线程。重写构造函数和start方法以实现此功能。 - OldCurmudgeon

19

自从Java 1.0发布以来的20多年里,被认为是良好设计模式的东西已经发生了改变。然而,Java致力于向后兼容,这意味着可能使用较差设计模式的旧代码仍将工作。

我的一个讨厌之一是StringBuffer。它的方法从来没有很好地同步过,十多年前就被取代了。但不幸的是,开发人员今天仍然可以使用它,甚至新的开发人员也在使用它,尽管它在他们开始使用Java之前就已经被弃用了。


2
选择阻塞可运行对象和线程之间并不涉及“设计模式”,这没有任何意义。这是两种不同的用例场景。 - specializt
设计模式包括组合和继承。您考虑了哪两种不同的用例?子类化“Thread”通常*仅限于重写run(),而其他方法很少覆盖。 - Peter Lawrey
@specializt 你可能在谈论另一种语言。我在谈论Java,而在Java中,Thread的代码第一行是class Thread implements Runnable。这意味着通过继承,您可以将重写的Thread传递到任何使用Runnable的地方,并且可以在Thread的构造函数中传递一个Runnable作为其默认实现。如果有人说的话让您感到困惑,那可能只是因为您不理解他们在说什么。这个问题是有意义的,因为它是一个常见的问题,请参见“Possible duplicate”。 - Peter Lawrey
类签名兼容并不改变这个问题和以上所有答案的无意义 - Runnable 仍然不是线程,它们永远不会自己异步运行。 - specializt
@specializt 不只是我,Google也不清楚Java中的类签名是什么意思 https://www.google.co.uk/webhp?#safe=off&q=java+class+signature - Peter Lawrey
显示剩余8条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接