IllegalThreadStateException 是线程处于不允许状态时抛出的运行时异常,最常见于对已启动线程重复调用 start();因 Java 线程生命周期规定 start() 仅能调用一次,状态从 NEW 变为 RUNNABLE 后不可重启,JVM 检测到即抛异常。

IllegalThreadStateException 是 Java 中一个运行时异常,当线程处于**不允许执行某操作的状态**时抛出,最常见的情形就是:对一个已经启动(start() 过)的线程再次调用 start() 方法。
为什么不能重复调用 start()?
Java 线程的生命周期中,start() 只能被调用一次。它会触发 JVM 创建底层操作系统线程,并将该线程状态从 NEW 变为 RUNNABLE。一旦状态改变,再次调用 start() 就违反了线程模型契约——线程不能“重启”或“二次启动”。JVM 检测到该非法操作,就抛出 IllegalThreadStateException。
典型触发场景
- 在
if (thread.isAlive()) { ... }判断不严谨的情况下,误判线程未启动而重复调用start() - 多线程环境下未加同步,两个线程同时判断并尝试启动同一个线程对象
- 把线程对象当作可重用资源,在线程执行完(进入
TERMINATED状态)后仍试图再次start()(注意:TERMINATED线程也不能重启) - 误以为
join()或sleep()后线程可再次启动
如何避免?
- 每个
Thread实例只调用一次start();如需多次执行任务,改用ExecutorService(如Executors.newCachedThreadPool())管理线程复用 - 启动前检查状态:可用
thread.getState() == Thread.State.NEW替代isAlive(),因为只有NEW状态才允许启动 - 若需控制任务执行时机,用
wait()/notify()、CountDownLatch或BlockingQueue等协作机制,而非反复启停线程 - 避免在线程已终止后保留其引用并尝试重启;应新建线程实例或使用线程池
简单示例对比
❌ 错误写法:
Thread t = new Thread(() -> System.out.println("run"));
t.start();
t.start(); // 抛出 IllegalThreadStateException
✅ 正确做法(复用任务,不复用线程):
立即学习“Java免费学习笔记(深入)”;
Runnable task = () -> System.out.println("run");
new Thread(task).start(); // 第一次
new Thread(task).start(); // 第二次 —— 新线程实例
线程对象本身不可重入,设计时牢记“启动一次,终结一生”。用好线程池,是规避这类异常最自然的方式。


















