应优先实现 Runnable 或 Callable 接口而非继承 Thread 类,因后者受限于单继承、不可复用、易引发线程安全问题;必须继承时需职责单一、正确重写 run()、避免构造器启动、不复用实例,并注意共享状态的同步控制。

直接继承 Thread 类实现多线程虽简单,但实际开发中需谨慎使用,它在灵活性、复用性和设计规范上存在明显局限。
避免重复继承导致的类结构僵化
Java 不支持多重继承,一个类若已继承了其他父类(如业务实体类、框架基类),就无法再继承 Thread。此时强行改造继承体系会破坏原有设计,增加耦合。
- 优先考虑 实现 Runnable 或 Callable 接口,它们与业务类可自由组合
- 若必须用 Thread 子类,应确保该类职责单一——仅负责线程控制逻辑,不混杂业务数据或服务功能
重写 run() 方法而非 start()
start() 是启动线程的唯一合法方式,由 JVM 负责调度;若误调 run(),只是普通方法调用,不会开启新线程,所有代码仍在当前线程执行。
- 务必重写 public void run(),并在其中编写真正要并发执行的逻辑
- 不要在 run() 中调用 this.start(),会造成非法状态异常
- 避免在构造器中启动线程(如 new MyThread().start()),易引发对象未完全初始化就被执行的问题
线程实例不可复用,每次运行需新建对象
Thread 对象生命周期与单次执行强绑定:一旦进入 TERMINATED 状态,再次调用 start() 会抛出 IllegalThreadStateException。
立即学习“Java免费学习笔记(深入)”;
- 不要缓存或池化自定义 Thread 子类实例
- 需要频繁启停任务时,改用 ExecutorService 管理线程池,提交 Runnable/Callable 即可
- 若封装为工具类,建议提供静态工厂方法返回新 Thread 实例,而非复用字段对象
注意实例变量的线程安全性
每个 Thread 子类实例默认拥有独立的成员变量副本,看似“天然线程安全”,但若多个线程共享同一实例(例如单例模式下复用 Thread 对象),或通过外部引用暴露了可变状态,则仍存在竞态风险。
- 尽量将任务数据通过构造参数传入,并设为 final
- 避免在 Thread 子类中持有静态可变状态或跨线程共享对象引用
- 如需共享资源,仍须配合 synchronized、Lock 或线程安全容器(如 ConcurrentHashMap)
继承 Thread 类适合教学演示或极简场景;生产环境更推荐组合优于继承的设计思路,用 Runnable + ExecutorService 构建清晰、可控、可扩展的并发模型。










