我知道Java中具体线程类和可运行接口之间的区别.使线程类可重写以供使用的需要是什么?可以通过实现Runnable接口来创建所有线程吗?如果线程类是必需的,那么用例会是什么?为什么我们有两种方法来解决同一个问题?
我知道Java中具体线程类和可运行接口之间的区别.使线程类可重写以供使用的需要是什么?可以通过实现Runnable接口来创建所有线程吗?如果线程类是必需的,那么用例会是什么?为什么我们有两种方法来解决同一个问题?
为什么Java同时提供线程类和可运行接口来创建线程?
简而言之,答案是"历史".
1995年,Java1.0定义了Thread
,这样您就可以扩展这个类,或者将Runnable
传递给构造函数.关于Java1.1,设计师们很清楚,扩展Thread
是一个糟糕的 Select .但现在修复已经太晚了.将Thread
改为final
类不再是一个选项,因为它会 destruct 向后兼容性.
向前滚动到2022年,同样的推理仍然适用.仍然有很多重要的遗留代码,程序员已经用包含应用程序逻辑的方法将Thread
扩展为覆盖run()
.代码运行良好...因此,迫使大量Java用户以"更好"的方式进行更新将是一个糟糕的商业决策.
他们当初为什么做出这个决定?谁知道呢!我的猜测是,早在1995年,他们就没有设想过线程池、执行器等问题,如果你扩展Thread
个线程,这些问题就会出现.(还有其他一些事情……如多年前被弃用的不安全或不可实施的Thread
种方法所示.)
一个可能的因素是Java1.0没有匿名的内部类.因此,为了使用构造函数参数方法,程序员需要声明一个扩展了Runnable
的命名类.扩展Thread
是一个"有吸引力"的 Select .IIRC,Java 1.1解决了这个语言缺陷.在Java8+中,我们还可以使用lambda表达式来定义线程可运行性.
记住:Java设计时线程数为a new thing.Java是最早支持它们的编程语言之一.(保证不犯错误的唯一方法是什么都不做.这通常是一个错误.)
可以通过实现
Runnable
接口来创建所有线程吗?
不,创建线程所涉及的所有逻辑实际上都在Thread
类中...以及它在JVM中的本机代码实现.用Java代码自己做这件事是不现实的.