必须显式处理 interruptedexception,因为它是协作式取消信号而非错误;忽略会导致中断状态丢失、任务无法响应 shutdownnow(),合规做法是业务逻辑中恢复中断后退出,工具方法中声明抛出异常。

必须处理,不能绕过。Java 把 InterruptedException 设为受检异常,不是为了增加麻烦,而是强制你面对线程协作中的“取消信号”。忽略它,等于关掉系统的紧急刹车。
为什么必须显式处理?
因为 Thread.sleep() 是典型的阻塞方法,它的执行依赖外部状态(比如时间到期)。中断不是错误,是协作式取消请求。编译器强制捕获,就是提醒你:线程可能被要求提前退出,你得决定怎么收尾。
- 不处理 → 编译失败,代码根本跑不起来
- 空 catch 或只打印堆栈 → 中断标志被清空,上层无法感知取消意图,任务可能卡死或无法响应 shutdownNow()
- 用
Thread.interrupted()判断再 sleep → 静态方法会清除状态,后续再进阻塞点仍可能抛异常,逻辑不可靠
两种合规处理路径
选哪条,取决于你写的是业务逻辑还是工具封装。
- 你是任务主体(如 Runnable、线程主循环):在 catch 里做清理(关流、释放锁、取消操作),然后 return 或 break,让线程自然终止
-
你是工具方法(如封装了 sleep 的 waitUntil()):调用
Thread.currentThread().interrupt()恢复中断状态,然后直接 throw e 或声明 throws InterruptedException,把决策权交给调用方
常见写法避坑示例
下面这些看着能过编译,但实际埋雷:
-
catch (InterruptedException e) { }—— 完全吞掉,中断信号消失 -
catch (InterruptedException e) { e.printStackTrace(); }—— 日志写了,但没恢复中断,上游 isInterrupted() 会返回 false -
public void run() { try { sleep(1000); } catch (...) { ... } }—— Runnable.run() 不允许 throws 受检异常,所以只能 catch;但 catch 后必须恢复中断,否则线程池 shutdownNow() 会失效
正确模板参考
业务线程中使用:
try {Thread.sleep(2000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); // 恢复状态
return; // 或 break 循环
}
工具方法中使用:
public void waitForReady() throws InterruptedException {Thread.sleep(500);
}











