我知道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代码自己做这件事是不现实的.

Java相关问答推荐

无法运行Java(已解决)

RDX触发ChoiceBox转换器(并按字符串值排序)

Saxon 9:如何从Java扩展函数中的net.sf.saxon.expr. XPathContent中获取声明的变量

Listview—在Android Java中正确链接项目时出错

@ IdClass with @ Inheritance(策略= InheritanceType. SINGLE_TABLE)

为什么我要创建一个单独的互斥体/锁对象?

具有多种令牌类型和段的复杂Java 17正则表达式

当涉及到泛型时,类型推理在Java中是如何工作的?

Java:使用Class.cast()将对象转换为原始数组

在Spring Boot中使用哪个Java类来存储创建时间戳?

如何解释Java中for-each循环中对Iterable的强制转换方法引用?

Java Mooc.fi Part 12_01.Hideout -返回和删除方法

迁移到Java 17后,日期显示不准确

内存和硬盘中的Zip不同,这会导致下载后的Zip损坏

Cordova Android Gradle内部版本组件不兼容

插入中的JOOQ序列,设置为VS值

JavaFX复杂项目体系 struct

Cucumber中第二个网页的类对象未初始化

如何转换Vector<;对象>;转换为int?

Java ModbusRTU写寄存器