ReentrantLock 需配合 Condition 实现线程协作,支持可中断、超时等待及多条件选择性唤醒;await 必在持锁时调用,自动释放并重竞争锁;需 try-finally 保证 unlock,公平锁降低吞吐量。

ReentrantLock 本身不直接实现线程协作,但它提供了比 synchronized 更精细的锁控制能力,配合 Condition 对象,才能构建出灵活、可中断、可超时、多等待队列的线程协作逻辑。
用 Condition 实现生产者-消费者模型
ReentrantLock 的 newCondition() 方法可创建与该锁绑定的 Condition 实例,每个 Condition 独立维护一个等待队列,支持 signal/signalAll/await 操作。
例如,一个带容量限制的阻塞队列可定义两个 Condition:
- notFull:供生产者 await,当队列满时挂起;被消费者在 take 后 signal 唤醒
- notEmpty:供消费者 await,当队列空时挂起;被生产者在 put 后 signal 唤醒
关键点:await() 必须在 lock 持有状态下调用,且会自动释放锁并进入等待;被唤醒后重新竞争锁,成功获取后才从 await 返回。
立即学习“Java免费学习笔记(深入)”;
支持可中断和带超时的等待
Condition 提供了更健壮的等待方式:
- awaitNanos(long nanosTimeout) 或 awaitUntil(Date deadline):避免无限等待,适用于有响应时间要求的场景(如 RPC 调用等待结果)
- awaitUninterruptibly():忽略中断,适合不希望被外部干扰的核心协作流程
- await():响应中断,抛出 InterruptedException,便于上层统一处理取消逻辑
对比 synchronized + wait(),ReentrantLock + Condition 的等待可被精确控制,且中断状态不会丢失。
实现多条件等待与选择性唤醒
一个锁可关联多个 Condition,实现“按需唤醒”——这是 synchronized 无法做到的。
例如,一个任务调度器维护三种状态:待执行、暂停中、已取消。可为每种状态变化定义独立 Condition:
- onReady → signal readyCondition
- onPause → signal pausedCondition
- onCancel → signal cancelledCondition
不同线程可 await 不同 Condition,避免虚假唤醒和无谓竞争,提升协作精度和性能。
注意公平性与性能权衡
ReentrantLock 构造时可指定是否公平(new ReentrantLock(true))。公平锁保证等待时间最长的线程优先获取锁,但会显著降低吞吐量。
协作逻辑中若频繁争抢锁(如高并发下的信号通知),建议使用非公平锁(默认),除非业务明确要求严格 FIFO 顺序(如金融交易指令排队)。
另外,lock()/unlock() 必须成对出现在 try-finally 中,防止因异常导致锁未释放:
lock.lock();
try {
// 协作逻辑,可能 await
} finally {
lock.unlock();
}


















