线程中断与终止
2026/8/24大约 2 分钟
线程中断与终止
使用
interrupt()优雅地中断线程,理解待决中断,以及为何废弃stop()、suspend()。
interrupt() 中断机制
Thread.interrupt() 只是在目标线程中设置一个中断标志并立即返回,线程并不会被实际中断,会继续往下执行。
休眠线程的中断:线程在 sleep() 时收到中断,会抛出 InterruptedException,捕获后需自行决定是否退出:
public void run() {
try {
Thread.sleep(20000);
} catch (InterruptedException e) {
System.out.println("interrupted while sleeping");
return; // 处理完中断异常后返回,线程消亡
}
System.out.println("leaving normally");
}注意:如果把 catch 块中的 return 注释掉,线程会继续往下执行,而不会被中断。
待决中断
如果线程在调用 sleep() 之前就被中断,该中断称为待决中断——它会在刚调用 sleep() 时立即抛出 InterruptedException。
Thread.currentThread().interrupt(); // 先设置中断标志
try {
Thread.sleep(1000); // 立即抛出 InterruptedException
} catch (InterruptedException e) {
// 待决中断在此被捕获
}挂起与恢复:为什么废弃 suspend/resume
Thread.suspend() / resume() 已被淘汰,因为不安全、不稳定:
- 如果在不合适的时候挂起线程(比如持有共享资源锁时),其他线程等待该锁,而线程被挂起无法释放——产生死锁
- 长时间计算期间挂起线程也可能导致问题
正确做法:通过标志位 + 协作式中断控制线程的挂起、恢复与终止。
终止线程的正确方式
- 使用中断标志:循环中检查
Thread.interrupted(),收到中断后清理资源并退出 - 不要使用
Thread.stop():强制终止会释放所有锁,可能破坏对象状态的不变量 - 使用 volatile 标志位:通过
volatile boolean running控制循环退出(保证可见性)
public class Task implements Runnable {
private volatile boolean running = true;
public void stop() {
running = false; // 主线程调用,可见性由 volatile 保证
}
public void run() {
while (running && !Thread.currentThread().isInterrupted()) {
// 工作循环
}
// 清理资源后退出
}
}