Condition是ReentrantLock配套的精准等待/唤醒机制,支持多条件队列、精准signal唤醒、超时/中断等待,并通过while条件检查防虚假唤醒,显著优于synchronized中单一队列的wait/notify。

Condition 对象本身不直接“提升执行顺序控制”,而是为线程提供更精细、更灵活的等待/通知机制,从而让开发者能更准确地控制多个线程在特定条件下的协作顺序。
Condition 是 Lock 的配套等待队列
与 synchronized + wait/notify 不同,Condition 必须绑定在 ReentrantLock 上,一个 Lock 可创建多个 Condition 实例。每个 Condition 维护独立的等待队列,这使得不同业务逻辑(比如“缓冲区非空”和“缓冲区非满”)可以互不干扰地等待和唤醒。
- 避免 notifyAll 带来的无效唤醒:用 signal() 精准唤醒等待该条件的线程,减少竞争和上下文切换
- 支持条件化等待:线程可调用 await() 进入指定 Condition 的队列,直到其他线程调用 signal() 或 signalAll()
- 配合 while 循环检查条件:await() 返回不意味着条件已满足,必须重新判断,防止虚假唤醒
用 Condition 实现生产者-消费者顺序协作
典型场景中,Condition 让生产者和消费者按需阻塞、按需唤醒,真正实现“有数据才消费、有空位才生产”的严格顺序控制。
- 定义两个 Condition:
notFull(供生产者等待)和notEmpty(供消费者等待) - 生产者在 buffer 满时 await(notFull),写入后 signal(notEmpty);消费者在 buffer 空时 await(notEmpty),读取后 signal(notFull)
- 所有操作必须在 lock.lock()/lock.unlock() 保护下进行,且 await() 会自动释放锁,被唤醒后重新竞争锁
避免常见陷阱:中断、超时与条件重入
Condition 提供了更健壮的线程控制能力,但需主动使用才能发挥价值。
立即学习“Java免费学习笔记(深入)”;
- 支持响应中断:await() 可被 interrupt() 中断,抛出 InterruptedException,便于任务取消
- 支持超时等待:awaitNanos(long nanosTimeout) 或 awaitUntil(Date deadline),防止无限阻塞
- signal() 不释放锁,只将线程移入 AQS 同步队列;真正获得锁仍需等待当前持有者释放——这保证了唤醒后的执行顺序不会破坏临界区一致性
对比 wait/notify:为什么 Condition 更可控
synchronized 内置监视器只有一个隐式等待队列,notify() 随机唤醒,容易导致“唤醒错人”。而 Condition 显式建模业务语义,唤醒目标明确。
- wait/notify 必须在 synchronized 块内调用,且无法分离锁与条件;Condition 将锁(Lock)与条件(Condition)解耦
- 一个 Lock 多个 Condition,可为不同状态建模(如“读就绪”、“写就绪”、“关闭中”),调度逻辑清晰可读
- await() 自动释放锁并挂起,signal() 不立即恢复执行,而是让线程参与锁竞争——这种设计天然支持公平性与可预测的执行顺序


















