1. 引言
"到底该实现 Runnable 还是继承 Thread?" 这个问题在 Java 开发中经常被讨论。
本文将通过实际场景分析两种方式的优劣,帮你避开常见误区,选择更合适的方案。
2. 使用 Thread 类
先来看继承 Thread 的实现方式:
public class SimpleThread extends Thread {
private String message;
// 标准日志记录器和构造器
@Override
public void run() {
log.info(message);
}
}
启动这种线程有两种方式:
2.1 直接启动
@Test
public void givenAThread_whenRunIt_thenResult()
throws Exception {
Thread thread = new SimpleThread(
"SimpleThread executed using Thread");
thread.start();
thread.join();
}
2.2 通过线程池启动
@Test
public void givenAThread_whenSubmitToES_thenResult()
throws Exception {
executorService.submit(new SimpleThread(
"SimpleThread executed using ExecutorService")).get();
}
⚠️ 注意:这种方式的缺点很明显:
- 为了执行简单日志操作就写了这么多代码
- SimpleThread 无法继承其他类(Java 不支持多继承)
3. 实现 Runnable 接口
现在改用实现 Runnable 的方式:
class SimpleRunnable implements Runnable {
private String message;
// 标准日志记录器和构造器
@Override
public void run() {
log.info(message);
}
}
这个 SimpleRunnable 只是个任务单元,有多种执行方式:
3.1 通过 Thread 类执行
@Test
public void givenRunnable_whenRunIt_thenResult()
throws Exception {
Thread thread = new Thread(new SimpleRunnable(
"SimpleRunnable executed using Thread"));
thread.start();
thread.join();
}
3.2 通过线程池执行
@Test
public void givenARunnable_whenSubmitToES_thenResult()
throws Exception {
executorService.submit(new SimpleRunnable(
"SimpleRunnable executed using ExecutorService")).get();
}
关于 ExecutorService 的详细用法可参考 Java 线程池教程
3.3 Java 8+ 的 lambda 写法
从 Java 8 开始,Runnable 作为函数式接口可以直接用 lambda 表达式:
@Test
public void givenARunnableLambda_whenSubmitToES_thenResult()
throws Exception {
executorService.submit(
() -> log.info("Lambda runnable executed!"));
}
4. 对比分析:Runnable 还是 Thread?
简单粗暴地总结:优先使用 Runnable,原因如下:
✅ 设计原则更合理
- 继承 Thread 时,我们实际是在重写 Runnable 的方法(Thread 实现了 Runnable),这违反了 IS-A 原则
- 实现 Runnable 采用组合而非继承,扩展性更强
✅ 避免继承限制
- 继承 Thread 后无法再继承其他类
- 实现 Runnable 不影响继承体系
✅ 现代 Java 特性支持
- Java 8+ 可用 lambda 表达式简化代码
- 更符合函数式编程思想
❌ 继承 Thread 的坑
- 线程管理与业务逻辑耦合
- 难以复用线程资源
- 违背"组合优于继承"原则
5. 总结
通过对比可以清晰看出:
- 实现 Runnable 是更优雅的方案
- 继承 Thread 仅在特殊场景下适用(如需要操作 Thread 特有方法时)
- 现代开发中建议结合线程池 + lambda 使用 Runnable
本文代码示例可在 GitHub 仓库 获取完整实现