object.wait()被中断时抛出interruptedexception,必须捕获并调用interrupt()恢复中断状态,且wait()须在synchronized块内调用;结合循环条件决定是否退出,lock+condition需类似处理。

Java中Object.wait()在等待过程中被中断时会抛出InterruptedException,必须显式捕获并正确处理——不能简单忽略,也不能仅打印堆栈就完事。
必须捕获并恢复线程中断状态
wait()是可中断的阻塞方法,抛出InterruptedException意味着当前线程的中断标志已被清除。若只捕获异常却不重设中断状态,上层逻辑将无法感知本次中断,可能导致任务无法及时终止或资源泄漏。
- 正确做法:在catch块中调用
Thread.currentThread().interrupt()恢复中断标志 - 错误示例:
catch (InterruptedException e) { e.printStackTrace(); }——中断信号丢失 - 不推荐吞掉异常:
catch (InterruptedException e) { /* 忽略 */ }
结合业务逻辑决定是否退出等待循环
多数场景下wait()处于while循环中(用于条件等待),收到中断后应根据实际需求选择继续等待还是退出。
- 若中断表示“该停止等待了”,应在catch后跳出循环或返回
- 若只是临时中断(如超时重试),可记录日志后继续循环
- 典型模式:
while (!condition) { try { wait(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); break; } }
避免在synchronized块外调用wait
wait()必须在同步上下文中执行,否则抛IllegalMonitorStateException。中断处理逻辑也应放在同步块内,确保状态一致性。
- 不要把
wait()和异常处理拆到不同同步块中 - 同步范围应覆盖条件判断、wait调用及中断恢复逻辑
- 示例:先
synchronized(obj),再检查条件、调用wait()、捕获并恢复中断
与Lock+Condition配合时注意差异
如果使用ReentrantLock和Condition.await(),行为类似但API更明确:await()同样抛InterruptedException,且同样需要恢复中断状态;而awaitUninterruptibly()则忽略中断,慎用。
-
Condition.await()必须在lock持有状态下调用,异常处理方式与Object.wait()一致 - 不要混用
synchronized和Lock机制来保护同一共享状态 - 优先考虑
LockSupport.park()/unpark()等更底层工具时,需自行管理中断逻辑
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











