Java中wait()抛出的InterruptedException必须恢复中断状态而非忽略,应配合while循环和守卫条件使用,并优先采用BlockingQueue等高级并发工具替代裸wait。

Java 中 wait() 方法会抛出 InterruptedException,这是必须处理的受检异常。优雅处理的关键不是简单吞掉异常,而是尊重线程中断意图,同时保障资源安全和状态一致性。
明确中断语义,不忽略 InterruptedException
InterruptedException 表示当前线程被其他线程通过 interrupt() 显式中断,这是协作式线程终止的重要机制。直接捕获后空 catch(如 catch (InterruptedException e) {})会丢失中断状态,破坏上层调用方的中断感知能力。
- 正确做法:在 catch 块中调用
Thread.currentThread().interrupt()恢复中断状态 - 避免在循环中反复 wait 时未重置中断标志,导致后续逻辑无法响应中断
配合 while 循环做条件等待,而非盲目重入
wait() 可能因虚假唤醒(spurious wakeup)提前返回,因此必须与 while 循环和守卫条件(guard condition)配合使用。中断处理也应嵌套在此结构中,确保退出时机合理。
- 守卫条件未满足且被中断 → 应退出等待逻辑,向上抛出或转为业务异常
- 守卫条件已满足 → 即使曾被中断,也应继续执行后续流程(中断只是“提醒”,非强制终止)
- 示例:等待队列非空时,需写成
while (queue.isEmpty()) { wait(); },并在 catch 中恢复中断后仍检查条件
封装 wait 调用,统一中断策略
重复编写带中断恢复的 wait 模板容易出错。可封装为工具方法,把守卫条件、超时、中断响应等逻辑收拢:
立即学习“Java免费学习笔记(深入)”;
- 定义
await(Condition condition, long timeout)方法,内部处理InterruptedException并重设中断标志 - 返回布尔值表示是否因超时/中断退出,或抛出自定义运行时异常(如
WaitInterruptedException)便于上层区分 - 避免在 synchronized 块内做耗时操作,防止阻塞其他线程;中断处理逻辑应轻量
结合现代并发工具,减少裸 wait 使用
直接使用 Object.wait() 属于底层同步原语,易出错。优先考虑更高层次的抽象:
-
BlockingQueue(如LinkedBlockingQueue)的take()/poll(timeout)已内置中断支持,异常处理更清晰 -
CountDownLatch、CyclicBarrier、Phaser等同步器对中断有统一约定,调用方只需捕获并响应 - 使用
LockSupport.park()/unpark()替代 wait/notify 时,同样需检查Thread.interrupted()并及时退出


















