Java 线程的 run()当线程启动时,JVM 在该线程上调用该方法。要让线程有事可做,您可以创建 Thread 的子类并覆盖其 run() 方法,或者(首选)您可以为线程的构造函数提供 Runnable。没关系。
我正在创建 Thread 的子类并覆盖 run,但我意识到我无法像预期的那样保护该方法,因为 Thread.run() 是公共(public)的。然后我意识到为什么:它必须是公开的,因为 Thread 实现了 Runnable。但是为什么要实现 Runnable 呢?
这似乎不合逻辑。线程是 startable (从当前线程),但你不会以与 run() 一个 Runnable (从当前线程)相同的方式运行它;线程自行运行(在自己的线程上)。如果您确实手动调用了 Thread 的 run 方法,那么您并没有将其用作 Thread,而只是一个重量级的 Runnable。
由于这种设计,任何可以访问 Thread 对象的代码都可以调用其公共(public) run 方法,并可能会插入不打算公开或设计为以这种方式调用的代码。它还允许像这样非常奇特的事情:
Thread.currentThread.run();
Thread 实现 Runnable 是否有合法用途但我没有看到?
最佳答案
原因是“向后兼容”。
Thread
类起源于 Java 1.0 ... 或更早版本。在那些日子里,Java 没有内部类,因此没有一种轻量级的方法来实现 Runnable
实例。如果您查看那个时代的旧线程示例和教程,通常会看到扩展 Thread
并覆盖 run()
方法的类。
随着时间的推移,人们意识到扩展 Thread
并不是一个好主意(出于各种原因)。但是,Thread
设计无法更改,因为这会使旧的 Java 代码与新的 JVM 不兼容。
Is there a legitimate use for Thread implementing Runnable that I'm not seeing?
这取决于你所说的“合法”是什么意思。
早期编写的旧代码不是“非法”的,因为它以旧的方式做事。没有什么“坏”的地方。
存在可能 场景,其中扩展 Thread 并覆盖
run()
方法确实有意义。例如,您可能希望run()
实现一些特殊的机制来将信息传入或传出提供的Runnable
,或者实现一些特殊的异常处理,或者...使线程“可重新启动”。在某些情况下,您甚至可能希望直接在线程对象上调用
run()
。例如,如果您收到一些扩展Thread
的“狗早餐”代码,并且您必须将其转换为在线程池中运行 修改原始代码。您可能会考虑实例化繁琐的线程类并将实例作为可运行对象传递给线程池以运行。 (是的……太可怕了!)
关于java - Thread为什么要实现Runnable?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18305953/