Java线程中断是协作式通知而非强制终止,通过设置中断标志位并由线程主动响应实现;interrupt()设标志,isInterrupted()查且不重置,interrupted()查且清空标志。

线程中断不是强制杀死,而是协作式通知
Java 中没有安全的「强行终止线程」机制,Thread.stop() 早在 JDK 1.2 就被废弃,因为它会破坏对象状态、导致锁未释放、资源泄漏。真正的线程中断是通过设置中断标志位 + 线程主动响应来完成的。关键在于:中断只是发个信号,线程要不要停、何时停,由它自己决定。
interrupt()、isInterrupted() 和 Thread.interrupted() 的区别
这三个方法最容易混淆,用错会导致中断状态丢失或判断失效:
-
thread.interrupt():对目标线程设置中断状态(即把它的中断标志位设为true) -
thread.isInterrupted():返回该线程当前的中断状态,**不重置标志位**(可多次调用得到相同结果) -
Thread.interrupted():返回**当前线程**的中断状态,并**立即清空该标志位**(下次调用就变成false)——这是静态方法,且带副作用
常见错误:在循环中写 if (Thread.interrupted()) break;,看似合理,但如果循环体里其他代码(比如某次 I/O 调用)也触发了中断检查,就可能提前清空标志,导致后续判断失效。
阻塞状态下如何响应中断(sleep、wait、join、LockSupport.park)
这些方法在被中断时会立即抛出 InterruptedException,并**自动清除中断状态**。这是设计使然,但也是陷阱源头:
立即学习“Java免费学习笔记(深入)”;
- 必须在
catch块里决定是否「恢复中断」——多数情况下应重新调用Thread.currentThread().interrupt() - 不恢复的话,上层调用者(比如线程池或框架)将无法感知本次中断意图
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// 中断发生,当前线程中断标志已被清空
Thread.currentThread().interrupt(); // 恢复中断状态,供外层判断
return; // 或抛出自定义异常
}
运行中线程如何安全退出(非阻塞场景)
当线程在纯计算、遍历集合、处理网络包等非阻塞逻辑中,需手动轮询中断状态:
- 不要只依赖
while (!Thread.interrupted())—— 因为interrupted()是静态方法且会清空状态,下次循环就失效 - 推荐用
Thread.currentThread().isInterrupted(),它不改变状态,适合反复检查 - 若使用
ExecutorService,应配合shutdownNow()(发送中断)+awaitTermination()(等待退出),并确保提交的任务能响应中断
while (!Thread.currentThread().isInterrupted()) {
doSomeWork();
// 长耗时操作中建议插入检查,避免响应延迟过高
if (someCondition && Thread.currentThread().isInterrupted()) {
break;
}
}
最常被忽略的是:中断状态可能在任意时刻被设置,而你的任务逻辑如果没做检查,或者捕获了 InterruptedException 却没恢复标志,线程就会“假装没收到”,继续跑下去。安全停止的本质,是让每个执行路径都对中断保持敏感,而不是指望某个魔法开关一键关闭。











