Condition 接口与等待唤醒机制:对标 Object.wait/notify 的精准控制
在中,线程通信依赖于wait()notify()必须依附在同一个对象监视器上;不能精确唤醒指定线程;不支持多条件队列管理。为了解决这些问题,JDK5 引入了Condition 接口,配合使用,提供更灵活、更精确的等待/唤醒机制。Condition是的高级版,底层依托实现。Condition是 Java 并发通信的精细化工具,它将传统机制演进为多队列、可控、精确唤醒的模式。掌握Condition,你
文章目录
《Condition 接口与等待唤醒机制:对标 Object.wait/notify 的精准控制》
一、前言:为什么需要 Condition
在 synchronized 中,线程通信依赖于 wait() / notify(),但存在明显局限:
- 必须依附在同一个对象监视器上;
- 不能精确唤醒指定线程;
- 不支持多条件队列管理。
为了解决这些问题,JDK5 引入了 Condition 接口,配合 ReentrantLock 使用,
提供更灵活、更精确的等待/唤醒机制。
一句话:
Condition是Object.wait/notify的高级版,底层依托LockSupport.park/unpark实现。
二、Condition 的创建与基本使用
Condition 必须依附于一个显式锁(通常是 ReentrantLock):
ReentrantLock lock = new ReentrantLock();
Condition condition = lock.newCondition();
常用方法
| 方法 | 说明 |
|---|---|
await() |
当前线程等待(释放锁,进入等待队列) |
signal() |
唤醒一个等待线程 |
signalAll() |
唤醒所有等待线程 |
awaitNanos(long nanos) |
等待指定纳秒时间 |
awaitUntil(Date deadline) |
等待直到某个时间点 |
awaitUninterruptibly() |
不可中断等待 |
三、工作原理与底层机制
(1)内部结构
每个 Condition 都维护一个独立的 等待队列(Condition Queue),
与 AQS 的同步队列(Sync Queue)分离。
流程概览:
ReentrantLock
├── AQS 同步队列(锁竞争队列)
└── Condition 等待队列(每个 Condition 独立)
(2)await() 的底层逻辑
源码简化:
public final void await() throws InterruptedException {
if (Thread.interrupted()) throw new InterruptedException();
Node node = addConditionWaiter();
int savedState = fullyRelease(node);
while (!isOnSyncQueue(node)) {
LockSupport.park(this); // 阻塞当前线程
}
acquireQueued(node, savedState);
}
执行流程:
- 当前线程持有锁,调用
await(); - 线程被加入 Condition 队列;
- 释放锁(让出执行权);
- 使用
LockSupport.park()挂起线程; - 被唤醒后重新加入 AQS 队列竞争锁;
- 成功获得锁后从
await()返回。
(3)signal() 的底层逻辑
public final void signal() {
Node first = firstWaiter;
if (first != null)
doSignal(first);
}
执行流程:
- 将 Condition 队列中的第一个等待节点转移到 AQS 同步队列;
- 调用
LockSupport.unpark()唤醒对应线程; - 被唤醒的线程重新竞争锁;
- 获得锁后从
await()返回。
(4)Condition 与 LockSupport 的关系
- Condition 通过 AQS 管理等待队列;
- 线程挂起与唤醒由
LockSupport.park/unpark实现; - 精确唤醒机制比
notifyAll()更高效。
四、Condition vs Object.wait/notify
| 对比项 | Condition | Object.wait/notify |
|---|---|---|
| 所属锁类型 | ReentrantLock | synchronized |
| 等待队列 | 独立多队列 | 共享单队列 |
| 唤醒粒度 | 精确(指定条件) | 模糊(随机线程) |
| 可中断等待 | ✅ 支持 | ✅ 支持 |
| 多条件支持 | ✅ 支持多个 Condition | ❌ 仅一个监视器 |
| 底层实现 | LockSupport.park/unpark | JVM Monitor 机制 |
Condition 提供“多等待队列”的能力,可针对不同条件变量分别控制等待与唤醒逻辑。
示例:
ReentrantLock lock = new ReentrantLock();
Condition notFull = lock.newCondition();
Condition notEmpty = lock.newCondition();
可分别控制“队列满/空”的不同等待队列。
五、典型应用场景与代码示例
(1)生产者-消费者模型(多 Condition 版本)
class BoundedBuffer {
final Lock lock = new ReentrantLock();
final Condition notFull = lock.newCondition();
final Condition notEmpty = lock.newCondition();
final Object[] items = new Object[5];
int putptr, takeptr, count;
public void put(Object x) throws InterruptedException {
lock.lock();
try {
while (count == items.length)
notFull.await();
items[putptr] = x;
if (++putptr == items.length) putptr = 0;
++count;
notEmpty.signal(); // 唤醒消费者
} finally {
lock.unlock();
}
}
public Object take() throws InterruptedException {
lock.lock();
try {
while (count == 0)
notEmpty.await();
Object x = items[takeptr];
if (++takeptr == items.length) takeptr = 0;
--count;
notFull.signal(); // 唤醒生产者
return x;
} finally {
lock.unlock();
}
}
}
说明:
notFull:队列满时阻塞生产者;notEmpty:队列空时阻塞消费者;- 精准控制唤醒目标,无需
notifyAll()带来的无效唤醒。
(2)线程池任务队列(内部机制)
在 ThreadPoolExecutor 中,BlockingQueue.take() 也是基于 Condition 实现的等待/唤醒。
六、面试高频问题与回答模板
| 问题 | 答案要点 |
|---|---|
| Q1:Condition 是什么? | Condition 是配合 ReentrantLock 使用的线程等待/通知机制。 |
| Q2:Condition 如何实现等待? | await() 会释放锁、加入 Condition 队列并通过 LockSupport.park() 挂起线程。 |
| Q3:signal() 如何唤醒线程? | 将 Condition 队列中的节点转移到 AQS 队列,并调用 LockSupport.unpark() 唤醒。 |
| Q4:Condition 为什么比 wait/notify 更强? | 可支持多个独立条件队列,实现精准唤醒,避免无谓唤醒。 |
| Q5:await() 和 signal() 必须在锁内执行吗? | 必须,否则会抛 IllegalMonitorStateException。 |
| Q6:Condition 支持超时等待吗? | 支持,await(long, TimeUnit) 可实现定时等待。 |
| Q7:Condition 和 AQS 的关系? | Condition 是 AQS 的扩展机制,依托 AQS 的同步与等待队列。 |
结语
Condition 是 Java 并发通信的精细化工具,
它将传统 wait/notify 机制演进为多队列、可控、精确唤醒的模式。
掌握 Condition,你就理解了 AQS 内核中“线程通信”的真正原理,
也是 ReentrantLock、BlockingQueue、ThreadPoolExecutor 等组件的基础。
下一篇,我将写——
《Semaphore 信号量机制:限流与并发控制的经典实现》,
正式进入“并发限流与资源控制”部分。
更多推荐



所有评论(0)