acquireUninterruptibly适用于必须完成、不可因中断放弃的关键操作,如资源清理、事务收尾、日志落盘、shutdown同步等待等;它确保许可一定获取,避免状态不一致,但不适用于响应式接口或需兼容标准中断协议的场景。

acquireUninterruptibly 适合用在“必须完成、不能因中断而放弃”的关键操作中,比如资源清理、事务收尾、日志落盘或 shutdown 阶段的同步等待。
需要确保许可一定拿到的场景
当业务逻辑依赖于“已成功进入临界区”这个前提,且不允许因外部中断导致流程跳过或状态不一致时,就该用 acquireUninterruptibly。例如:释放数据库连接前必须先完成当前事务提交,此时若被中断而跳过 acquire,后续 release 就会错配甚至空指针。
- 典型例子:线程池关闭时,要求所有正在执行的清理任务必须跑完,哪怕调用了 interrupt
- 不适用于响应式服务接口——用户请求超时后应快速失败,而不是卡死等许可
中断信号由上层统一管理的模块
如果整个组件的中断策略是集中控制(比如通过一个 volatile 标志位 + 轮询),就不需要每个 acquire 都响应 Thread.interrupt()。此时用 acquireUninterruptibly 可避免中断状态被意外清除又未处理的隐患。
- 常见于后台守护线程、定时聚合任务、批处理管道等生命周期明确的长期运行任务
- 注意:和 acquire 混用会导致部分线程响应中断、部分不响应,调试困难
对公平性与确定性要求高的资源协调
在强一致性要求的资源池中(如硬件设备句柄、License 许可证),获取失败可能引发下游连锁故障。acquireUninterruptibly 虽不保证绝对公平,但能消除因中断导致的许可获取顺序跳跃,使排队行为更可预测。
立即学习“Java免费学习笔记(深入)”;
- 例如:某许可证服务器只允许 5 个并发调用,所有客户端都用 acquireUninterruptibly,就能确保第 6 个请求一定等到前一个释放后才开始,不会因某个线程被中断而“插队”或漏计数
- 性能略低(每次 park/unpark 多两次 volatile 写),但换来的是行为稳定
不适用于需要配合标准中断协议的场景
如果模块要兼容 Future.cancel(true)、ExecutorService.shutdownNow() 或 Spring 的 @Async 中断传播,就不要用 acquireUninterruptibly。它会静默吞掉中断,使上层无法感知等待线程是否已响应终止信号。
- Web 请求处理、RPC 调用、消息消费等对响应时间敏感的路径,优先选 tryAcquire(timeout, unit)
- 若真要用 acquireUninterruptibly,请确保 release 一定在 finally 块中执行,否则许可泄漏风险极高


















