Java中的线程中断(Interruption)是一种协作式机制,用于通知一个线程“有人希望你停止正在做的事情”。它并非强制终止线程(像已废弃的
Thread.stop() 那样),而是一种礼貌的请求,线程自身拥有决定如何响应的完全控制权。

中断相关核心API
所有中断逻辑都围绕 Thread 类的三个方法展开:

方法 说明
void interrupt() 发起中断。设置目标线程的“中断状态”为 true。如果目标线程正因 sleep(), wait(), join() 而阻塞,则会抛出
InterruptedException,并清除中断状态。
boolean isInterrupted() 检查中断状态。返回线程的中断状态,不清除状态标志。
static boolean interrupted() 检查并清除中断状态。返回当前线程的中断状态,然后将中断状态设置为 false。
响应中断的两种模式
模式一:处理InterruptedException
当线程在可中断的阻塞方法(如 sleep(), wait(), join())中被中断时,这些方法会抛出 InterruptedException。这是最直接的中断通知。
标准处理方式:要么向上层抛出异常,要么在 catch 块中恢复中断状态(以便调用者能感知),然后退出。

java
public void run() {
try {
while (!Thread.currentThread().isInterrupted()) {
// 执行一些工作…
Thread.sleep(1000); // 可能被中断
}
} catch (InterruptedException e) {
// 当sleep被中断时进入此块
System.out.println(“线程在休眠时被中断,准备退出。”);
// 恢复中断状态:非常重要!因为catch异常后中断状态已被清除。
Thread.currentThread().interrupt();
// 可以选择直接返回,结束run方法
return;
}
System.out.println(“线程正常退出(通过检查中断状态)。”);
}
模式二:轮询中断状态
对于没有调用可中断阻塞方法的线程,需要在其任务循环中定期检查中断状态。

java
public void run() {
// 每次循环前检查中断状态
while (!Thread.currentThread().isInterrupted()) {
// 执行一段耗时的计算,但未调用sleep/wait等
doSomeHeavyCalculation();
}
System.out.println(“线程通过轮询检测到中断,优雅退出。”);
// 可以进行必要的资源清理
}
关键陷阱与最佳实践
陷阱:吞掉InterruptedException而不恢复中断状态

java
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// 错误!仅仅打印日志,中断状态已被清除,上层调用者无法知道发生了中断。
log.error(“被打断了”, e);
}
正确做法:

java
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// 恢复中断状态
Thread.currentThread().interrupt();
// 根据情况:要么直接返回/抛出异常,要么忽略中断继续执行(需有充分理由)
return;
}
实战示例解析
回顾文中的四个例子:

例1:线程不检查中断状态也不调用可中断方法,interrupt() 无效。

例2:线程在循环中轮询 isInterrupted() 并主动返回,正确响应中断。

例3:线程在 sleep() 中被中断,捕获异常后没有恢复中断状态,导致循环继续,未能退出。

例4:在捕获 InterruptedException 后,调用 Thread.currentThread().interrupt() 恢复中断状态,随后轮询检查到中断,成功退出。这是标准模式。

总结:如何设计可中断的任务
如果任务代码会调用可中断的阻塞方法,确保捕获 InterruptedException 并在处理后恢复中断状态,然后尽快退出 run() 方法。

如果任务是纯计算型,在循环或关键点定期调用 Thread.currentThread().isInterrupted() 进行检查。

对于无法立即停止的清理操作,可以忽略中断请求,但必须记录。

将中断视为一个礼貌的请求,而非命令。线程的最终停止应由其自身逻辑控制。

通过协作式中断,我们可以实现线程的优雅停止,避免资源泄漏和数据状态不一致,这是编写健壮并发程序的基本功。