awaituninterruptibly()并非jdk标准api,condition接口仅提供响应中断的await()等方法;需手动捕获interruptedexception并恢复中断状态后继续循环等待,以模拟不可中断语义。

Condition.awaitUninterruptibly 并不是 Java 标准库中 java.util.concurrent.locks.Condition 接口或其实现类(如 AbstractQueuedSynchronizer.ConditionObject)提供的方法 —— 它**不存在于 JDK 的 public API 中**。
也就是说,你无法直接调用 condition.awaitUninterruptibly()。JDK 的 Condition 只提供以下主要等待方法:
-
await():可被中断,抛出InterruptedException -
awaitNanos(long)、awaitUntil(Date)等:也都响应中断
如果你需要“不可中断”的等待语义(即忽略线程中断信号、持续等待直到被 signal() 唤醒),必须**手动实现**,核心思路是:在捕获 InterruptedException 后不清除中断状态,也不抛出异常,而是继续循环等待。
如何模拟 awaitUninterruptibly 行为
典型写法如下(需配合 ReentrantLock 和 Condition 使用):
lock.lock();
try {
while (!someConditionMet()) {
try {
condition.await();
} catch (InterruptedException e) {
// 忽略中断,但建议恢复中断状态(见下文说明)
Thread.currentThread().interrupt(); // 可选:保留中断标记
// 不 throw,不 return,继续循环
}
}
} finally {
lock.unlock();
}
注意:这并非真正“不可中断”,而是**屏蔽中断响应** —— 线程仍可能被中断(Thread.interrupted() 会返回 true),但你的逻辑选择不退出等待。
为什么不能简单丢弃中断状态?
Java 的中断机制是协作式设计,粗暴忽略中断可能影响上层框架(如 ExecutorService、ForkJoinPool)的正常关闭或超时控制。因此更稳妥的做法是:
- 捕获
InterruptedException - 调用
Thread.currentThread().interrupt()恢复中断状态 - 继续等待(不退出循环)
这样既满足“等待不被中断打断”的业务需求,又尊重了中断协议,避免隐藏中断信号造成难以排查的问题。
替代方案:使用 LockSupport.park()(慎用)
底层 Condition.await() 实际基于 LockSupport.park(),而 park() 本身不响应中断(仅响应 unpark() 或超时)。但直接使用 park/unpark 绕过 Condition 会丢失条件谓词检查、队列管理、公平性等关键保障,容易出错,**不推荐在业务代码中替代 Condition**。
第三方库支持(如 Guava)
Guava 库曾提供 AbstractIdleService 等内部工具,但也不暴露 awaitUninterruptibly。Spring Framework 或其他框架也未封装该方法。目前主流生态中,**都要求开发者自行处理中断逻辑**,没有标准化的“不可中断等待”API。
本质上,Java 的设计哲学是“中断应被尊重”,所以没有提供开箱即用的不可中断等待 —— 所谓“不可中断”,其实是应用层对中断的主动忽略与重置,而非 JVM 或并发包层面的禁用。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











