应避免多次调用同一线程对象的start()方法,正确做法是仅在NEW状态下启动、改用一次性线程设计、优先使用线程池、或通过多次调用run()实现重复执行。

避免多次调用同一个线程对象的 start() 方法,核心是**不让它发生**,而不是等抛出 IllegalThreadStateException 再去捕获或处理。这个异常是 JVM 对明显逻辑错误的硬性拦截,说明代码设计本身有问题。
检查线程状态再启动
每次调用 start() 前,先确认线程是否还处于 NEW 状态:
- 使用 thread.getState() == Thread.State.NEW 判断
- 只在为 NEW 时才调用 start(),否则跳过或记录提示
- 注意:getState() 返回的是瞬时快照,多线程环境下需配合同步机制(如 synchronized、volatile 标记)保证判断与启动的原子性
改用一次性线程设计
让每个 Thread 实例只负责一次任务,执行完就丢弃:
- 不要反复复用同一个 Thread 对象
- 需要重复执行相同逻辑?重新 new 一个 Thread 实例再启动
- 避免在类字段中长期持有可启动的线程引用,防止误调用
优先使用线程池替代手动 start()
绝大多数业务场景不需要也不应该手动管理线程生命周期:
- 用 ExecutorService 提交 Runnable 或 Callable,由池统一调度
- 线程复用由框架保障,完全规避 start() 调用时机问题
- 支持定时、周期、批量等高级能力,更健壮、易维护
用 Runnable + 多次执行代替重复 start()
start() 不可重入,但 run() 方法可以被任意调用:
- 把业务逻辑写在 Runnable.run() 中
- 需要多次执行?直接多次调用 run()(在当前线程),或封装成新线程启动
- 适合轻量、无需并发隔离的场景,避免线程创建开销

















