线程中断是Java中协作式停止线程的机制,通过interrupt()设置中断状态,阻塞方法抛出InterruptedException并清空中断状态;捕获异常后应调用Thread.currentThread().interrupt()恢复状态,确保中断信号不丢失,遵循“捕获→恢复→退出或传播”原则,避免忽略异常或空catch,保证线程安全退出。

在Java中,线程中断是一种协作机制,用于通知线程应停止当前工作并提前退出。线程中断并不会强制终止线程,而是通过设置中断状态和抛出 InterruptedException 来提醒线程“你被中断了”。正确捕获和处理中断异常,是编写健壮并发程序的关键。
理解线程中断机制
Java中的线程中断依赖于三个核心方法:
- thread.interrupt():设置目标线程的中断状态为true
- Thread.currentThread().isInterrupted():检查当前线程是否被中断(不清除状态)
- Thread.interrupted():检查并清除当前线程的中断状态
当一个线程在调用如 wait()、sleep()、join() 等阻塞方法时被中断,jvm会抛出 InterruptedException,同时自动清除中断状态。
捕获 InterruptedException
在可能抛出中断异常的方法中,必须显式捕获 InterruptedException。常见的使用场景如下:
立即学习“Java免费学习笔记(深入)”;
例如,在一个执行长时间任务的线程中:
public class SleepTask implements Runnable { public void run() { try { Thread.sleep(10000); } catch (InterruptedException e) { // 捕获中断异常 System.out.println("线程被中断,准备退出"); // 重新设置中断状态 Thread.currentThread().interrupt(); } } }
注意:一旦捕获到 InterruptedException,中断状态已经被清除。如果需要让上层代码知道该线程曾被中断,应该手动调用 Thread.currentThread().interrupt() 恢复中断状态。
如何正确处理中断
处理中断的核心原则是:尊重中断语义,及时清理资源,并决定是否继续传播中断信号。
- 不要忽略 InterruptedException。空catch块会破坏协作机制
- 若方法不能继续运行,应在清理后退出
- 若方法是工具方法或库代码,建议抛出中断异常或向上层传递中断状态
示例:在循环任务中响应中断
while (!Thread.currentThread().isInterrupted()) { try { // 执行任务逻辑 doWork(); } catch (InterruptedException e) { // 被中断,退出循环 Thread.currentThread().interrupt(); // 恢复中断状态 break; } }
避免中断状态丢失
常见错误是在捕获异常后不恢复中断状态,导致调用栈上层无法感知中断。正确的做法是:
try { Thread.sleep(1000); } catch (InterruptedException e) { Thread.currentThread().interrupt(); // 关键:恢复中断 return; // 或抛出自定义异常 }
如果方法签名允许,也可以选择抛出 InterruptedException,由调用方决定如何处理。
基本上就这些。关键是要意识到中断是一种礼貌的请求,而不是强制命令。只要遵循“捕获→恢复→退出或传播”的模式,就能写出安全且可中断的多线程代码。


