start()只允许在线程处于new状态时调用,否则抛出illegalthreadstateexception;应通过原子标志位预防重复启动,而非依赖try-catch捕获该运行时异常。

Java 中 start() 方法本身不抛出受检异常,但调用它时若线程状态非法(如已启动、已终止),会直接抛出 IllegalThreadStateException —— 这是运行时异常,必须靠逻辑预防,而非 try-catch 被动捕获。
start() 的状态约束很严格
start() 只允许在线程处于 NEW 状态时调用。一旦调用成功,状态立即变为 RUNNABLE;之后再调用就会触发异常。线程结束(run 方法返回或抛出未捕获异常)后进入 TERMINATED 状态,也无法重启。
- 不能对已 start 的线程重复调用 start()
- 不能对已 run 完的线程再次 start()
- 不能对构造后未 start 的线程调用 run() 来“模拟启动”——这只会同步执行,不开启新线程
推荐做法:用标志位 + 同步控制启动逻辑
避免依赖 catch 异常来“兜底”,而是提前检查状态并阻止非法调用。常见模式是封装线程启动逻辑,内部维护一个原子布尔标志:
public class SafeRunner implements Runnable {
private final AtomicBoolean started = new AtomicBoolean(false);
private Thread thread;
public void start() {
if (started.compareAndSet(false, true)) {
thread = new Thread(this);
thread.start();
} else {
// 可选:记录日志或忽略,不抛异常
}
}
public void run() {
// 实际任务逻辑
}
}
异常处理不是重点,状态管理才是核心
IllegalThreadStateException 不该出现在正常流程中。它本质是编程错误信号,说明线程生命周期被误用。与其在调用处写 try-catch,不如:
- 确保每个线程对象只被 start 一次
- 避免共享同一 Thread 实例供多次启动
- 使用线程池替代手动管理 Thread 生命周期(更安全、可复用)
- 必要时通过
thread.getState()辅助调试,但生产代码中不应依赖它做流程判断
run() 内部的异常需要单独处理
start() 不管 run 执行过程中的异常,但未捕获的异常会导致线程终止。如需捕获,应在 run 方法内 try-catch,或设置 Thread.UncaughtExceptionHandler:
thread.setUncaughtExceptionHandler((t, e) -> {
System.err.println("Thread " + t.getName() + " crashed: " + e);
});
这不影响 start() 的调用逻辑,但能防止静默失败。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











