ReentrantLock通过newCondition()创建多个独立Condition实现多条件等待,每个Condition维护专属等待队列,支持精准唤醒;await/signal必须在lock保护下执行,需配合while循环防虚假唤醒。

ReentrantLock 通过 Condition 实现多条件等待,核心在于一个锁可绑定多个独立的 Condition 对象,每个 Condition 维护自己的等待队列,从而支持按不同业务逻辑精确唤醒指定线程组。
一个锁对应多个 Condition
与 synchronized 配合 Object.wait()/notify() 只能有一个隐式等待队列不同,ReentrantLock 可调用 newCondition() 方法创建任意多个 Condition 实例。每个 Condition 拥有独立的等待队列和唤醒机制,互不干扰。
- 比如生产者-消费者场景中,可分别定义 notFull 和 notEmpty 两个 Condition
- 当缓冲区满时,生产者调用 notFull.await() 进入该 Condition 的等待队列;消费者消费后调用 notFull.signal() 唤醒某个生产者
- 同理,notEmpty 专门管理等待消费的消费者线程
Condition 的 await/signal 必须在 lock 保护下执行
所有 Condition 操作都必须在持有对应 ReentrantLock 的前提下进行,否则抛出 IllegalMonitorStateException。
- 正确写法:先 lock.lock(),再调用 condition.await();await 会自动释放锁,并在被唤醒后重新竞争获取锁
- signal() 不释放锁,仅将等待队列中的一个线程移入同步队列,真正唤醒需等当前线程 unlock 后才可能获得锁继续执行
- 推荐使用 try-finally 确保 unlock,避免死锁
精准唤醒:signal() vs signalAll()
Condition 提供两种唤醒方式,适用于不同协作粒度:
立即学习“Java免费学习笔记(深入)”;
- signal():唤醒等待队列中**最早进入**的一个线程(FIFO),适合“一对一”或“单点触发”场景,减少不必要的上下文切换
- signalAll():唤醒该 Condition 上所有等待线程,适合状态变更影响全体、或需重新校验条件的场景(如多个消费者都需检查是否仍有数据可取)
- 注意:signal() 不保证唤醒的是你期望的那个线程,业务逻辑仍需配合 while 循环 + 条件判断(即“虚假唤醒”防护)
典型多条件协作示例:双队列任务调度器
假设系统维护两个任务队列:高优先级队列和普通队列,希望分别等待并唤醒对应处理线程。
- 定义 highPriorityCond 和 normalCond 两个 Condition
- 高优线程只 await highPriorityCond,普通线程只 await normalCond
- 当新高优任务到达,只 signal highPriorityCond;普通任务到达则 signal normalCond —— 避免唤醒无关线程
- 每个 await 前都用 while 检查队列是否真有对应任务,防止因中断或虚假唤醒导致误执行


















