继承Thread类不该优先选,因其违背面向对象原则:单继承导致类设计僵化、任务与线程强耦合无法复用、天然不支持线程安全单例、生命周期管理粗糙易出错。

继承 Thread 类在 Java 多线程开发中看似直接,实际存在多个结构性和设计层面的硬伤,不是“能用就行”,而是“不该优先选”。它的问题不在于语法错误,而在于违背面向对象原则、限制扩展能力、隐藏并发风险。
单继承导致类设计僵化
Java 只支持单继承,一旦类继承了 Thread,就彻底失去继承业务父类或框架基类的机会。比如你的订单服务本该继承 BaseService,若强行让它继承 Thread,就得放弃 BaseService 提供的通用日志、监控、事务等能力,或者改用组合方式绕开——而这恰恰说明 Thread 继承本身就不该承担业务逻辑。
- 无法再继承任何其他类,哪怕只是想复用一个工具基类
- 若已有继承关系(如 Spring 的 AbstractController),根本无法选择继承 Thread
- 后期想接入 AOP、代理、序列化等机制时,继承链冲突会越来越明显
任务与线程强耦合,无法复用和共享
每个 Thread 子类实例既是线程载体,又是任务容器,二者绑死。这带来两个后果:一是任务不能被多个线程共用;二是同一个任务逻辑无法灵活调度到线程池、定时器或异步上下文中。
- new 两个 MyThread 实例 → 启动两个独立线程,各自持有一份 private int count,无法协同卖票
- 想让多个线程执行同一份任务逻辑?只能靠 static 字段,但又引入同步难题
- 无法将任务提交给 ExecutorService,因为 Runnable/Callable 才是线程池的标准输入
天然不支持线程安全的单例模式
有人试图在 Thread 子类里加 static 单例字段,结果发现每次 new 都创建新对象,static 引用未同步初始化,多线程下可能被多次赋值;更严重的是,run() 里的懒加载逻辑会被多个线程同时触发——这不是“线程不安全”,而是“单例语义彻底失效”。
立即学习“Java免费学习笔记(深入)”;
- Thread 子类的构造本质是创建新线程实体,与“全局唯一实例”目标矛盾
- 静态字段初始化若无双重检查锁或静态内部类保障,必然出现竞态
- run() 方法不是共享入口,而是每个线程独占执行路径,无法统一控制初始化时机
生命周期管理粗糙,易出错
Thread 对象不可重复 start(),一旦进入 TERMINATED 状态就作废;在构造器里调用 start() 容易引发 this 逃逸;误调 run() 而非 start() 则变成同步方法调用,毫无并发效果——这些都不是边界情况,而是日常编码中高频踩坑点。
- start() 只能调用一次,频繁启停任务必须反复 new,性能差且难管理
- 构造即启动(new X().start())可能导致对象未初始化完成就被执行
- run() 是普通方法,调它不会开启新线程,新手极易混淆 start() 和 run()
真正需要并发执行的,从来不是“线程本身”,而是“任务逻辑”。把任务塞进 Thread 子类,就像把发动机焊死在方向盘上——能转,但再也换不了轮胎、加不了油、进不了维修站。


















