1. 中断阻塞状态的线程(如 sleep()
)
当线程因调用 sleep()
、wait()
、join()
等方法进入阻塞状态时,调用 interrupt()
会:
- 立即抛出
InterruptedException
,线程退出阻塞状态。 - 清除中断标志位(即
isInterrupted()
返回false
)。 - 需要通过捕获异常来处理中断逻辑。
示例代码:
Thread thread = new Thread(() -> {
try {
Thread.sleep(1000); // 阻塞状态
} catch (InterruptedException e) {
// 捕获到中断异常,需处理中断逻辑
System.out.println("线程在 sleep 时被中断!");
// 通常在此处清理资源或终止线程
}
});
thread.start();
thread.interrupt(); // 中断阻塞的线程
2. 中断正常运行状态的线程
当线程未处于阻塞状态时,调用 interrupt()
会:
- 设置线程的中断标志位(
isInterrupted()
返回true
)。 - 不会强制终止线程,需要开发者主动检查标志位并决定是否终止。
示例代码:
Thread thread = new Thread(() -> {
while (!Thread.currentThread().isInterrupted()) {
// 正常执行任务
System.out.println("运行中...");
}
System.out.println("线程被中断,正常退出!");
});
thread.start();
thread.interrupt(); // 设置中断标志位
关键区别总结:
场景 | 中断行为 |
---|---|
阻塞状态 | 抛出 InterruptedException ,清除中断标志,需通过异常处理响应中断。 |
正常运行状态 | 仅设置中断标志位(isInterrupted() == true ),需手动检查标志位并决定是否终止。 |
最佳实践:
- 处理阻塞中断:在
catch
块中合理处理中断(如清理资源),并根据需要重新设置中断标志:catch (InterruptedException e) { System.out.println("捕获到中断,重新设置中断状态"); Thread.currentThread().interrupt(); // 重新中断 }
- 响应非阻塞中断:在循环或耗时操作中定期检查
isInterrupted()
:while (!Thread.currentThread().isInterrupted()) { // 执行任务 }
注意事项:
- 不可中断的阻塞操作:某些 I/O 操作(如
Socket.read()
)不会响应中断,需通过关闭底层资源触发异常。 - 中断是协作机制:依赖线程自身的逻辑响应中断,而非强制终止。