为什么“implements Runnable”比“extends Thread”更受青睐?

34
Java Thread本身就实现了一个JavaRunnable!根据互联网上大多数专家的说法,实现Runnable优于扩展Thread!尽管我们不能在没有Thread类的情况下使用Runnable来利用线程
那么为什么我们更喜欢实现Runnable而不是扩展Thread呢?因为在这两种情况下,实际线程都是通过调用Thread实现的方法(即start()run())来说明的,虽然在Thread的情况下,我们并没有真正“扩展”Thread的功能,只是简单地重写了run()方法。

如果我听起来让人困惑,请原谅..!


线程很难控制。研究执行器以寻找更好的方法。它们接受可调用和可运行对象,而不是线程。 - Thorbjørn Ravn Andersen
5个回答

81
最常见的区别是:
当你扩展Thread类时,你不能扩展任何其他需要的类。(正如你所知,Java不允许继承多个类)。当你实现Runnable时,你可以为你的类节省一个空间,以便将来或现在可以扩展任何其他类。
然而,重要的区别是:
当你扩展Thread类时,每个线程都会创建一个唯一的对象并与之关联。当你实现Runnable时,它会将同一个对象共享给多个线程。
请查看此链接:http://manikandanmv.wordpress.com/tag/extends-thread-vs-implements-runnable/

如果在特定应用程序中,现在或将来我们不需要继承已经从Thread继承的类,并且该应用程序似乎没有内存问题,那么Runnable和Thread应该具有相等的机会吗? - Tariq
2
面向对象编程的基本原则是,“始终针对接口编程,而不是实现”。 - footy
感谢您在此发布链接并提供解释,这是非常积极的。 - Arjun Chaudhary
1
提供链接中的示例清楚地解释了Thread扩展和Runnable之间的差异。谢谢! - Sangram Anand

8
如果您的类扩展了Thread类,那么它将成为一个继承了Thread类属性的单个线程,因此会很重。 (当扩展Thread类时,每个线程都会创建唯一对象并与之关联,但当实现Runnable时,它会将同一对象共享给多个线程)。
如果您的类实现了Runnable接口,那么只需重写run()方法即可。因此该实例将创建一个单独的Thread,每个单独的线程都会单独运行,而不是作为程序中的单个重线程。 还有一件事,由于Java不支持多继承,如果您实现了Runnable,您将避免多重扩展的问题,因此如果您实现了Runnable接口,则可以扩展任何您需要的类,而不仅限于Thread类。

内存消耗如何?执行Runnable和new Thread()语句是否实际上相同?(如果同时多次调用则会很昂贵)? - gumuruh

5

一个类只能有一个父类,但可以实现任意数量的接口。通过扩展Thread,您放弃了对其他任何类进行子类化的机会。


3

Java只允许单继承,这意味着如果你继承了Thread类,就不能再继承其他任何类。而实现Runnable接口则没有这个限制,因为你的类可以实现任意数量的接口。


-5

你听起来很困惑。无论如何,我知道一个原因是我们可以使用Runnable实现相同的功能,所以我们应该选择它,因为如果我们实现Runnable,那么我们可以扩展其他类,而如果我们扩展Thread类则不可能。


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