Java中Condition.await()被中断时必抛InterruptedException,须捕获并调用Thread.currentThread().interrupt()恢复中断状态,再抛出或退出,否则破坏协作中断机制。

Java 中 Condition 的等待中断(即调用 await() 时被其他线程中断)必须通过捕获 InterruptedException 来响应,且需遵循“恢复中断状态”这一关键原则,否则会丢失中断信号,破坏协作式中断机制。
中断发生时一定会抛出 InterruptedException
Condition.await() 是可中断的等待方法,一旦线程在等待期间收到中断请求(Thread.interrupt()),它会立即退出等待,并抛出 InterruptedException。这不是可选行为,而是强制语义 —— 你不捕获,程序直接崩溃;你捕获却不处理,就等于吞掉了中断。
- 不能忽略该异常(例如只写
catch (InterruptedException e) {}) - 不能仅记录日志后丢弃,除非你明确知道当前上下文已彻底终止且无需传播中断
- 绝大多数情况下,应优先恢复中断状态:调用
Thread.currentThread().interrupt()
标准处理模式:捕获 → 恢复 → 退出或重试
典型写法是将 await() 放在循环中,并在捕获中断后恢复中断状态,再决定是否退出等待逻辑:
lock.lock();
try {
while (!shouldProceed()) {
try {
condition.await();
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); // 恢复中断标志
throw e; // 或根据业务选择 break / return / 抛出上层
}
}
// 执行后续操作
} finally {
lock.unlock();
}
- 恢复中断状态是为了让上层代码(如调用栈中的方法)能感知到中断并做统一处理
- 若在循环内捕获后直接
break,仍需先恢复中断,否则上层无法得知曾被中断 - 不建议在 catch 块里“吃掉”异常后继续循环,这会导致线程无法响应中断
与 Object.wait() 的中断处理逻辑一致
Condition.await() 的中断契约和 Object.wait() 完全一致:都是声明 throws InterruptedException,都要求调用者尊重中断。这意味着:
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
立即学习“Java免费学习笔记(深入)”;
- 所有基于 AQS 实现的
Condition(如ReentrantLock.newCondition())都遵循此规范 - 如果你封装了条件等待逻辑,对外暴露的方法也应声明
throws InterruptedException - 使用
awaitUninterruptibly()是例外情况,它屏蔽中断,但代价是无法响应外部停止指令,慎用
常见误区:误用 interrupted() 或忽略重入锁释放
有人用 Thread.interrupted() 清除中断状态后不再恢复,这是错误的 —— 它清除了标志却未通知调用方;还有人在 catch 块中忘记 unlock,导致死锁。
-
Thread.interrupted()是静态方法,会清除中断状态;而isInterrupted()不清除,更适合检测 - 务必确保
lock.unlock()在finally块中执行,哪怕发生了中断 - 不要在
await()外层加try-catch却不 re-throw 或恢复中断,这相当于拦截了系统级协作信号
中断不是异常,而是线程间协作的正常通信机制。正确处理 Condition.await() 的中断,本质是尊重线程的生命周期控制权 —— 不吞、不藏、不延迟响应。

















