需要多个condition是为了实现精准唤醒,避免synchronized中notifyall导致的无效唤醒;reentrantlock支持绑定多个condition,每个对应独立等待队列,可按业务语义(如notempty、notfull)调用signal()精确唤醒。

Java 中通过 Condition 可以在同一个锁(ReentrantLock)下创建多个等待队列,实现比 synchronized + wait/notify 更精细的线程唤醒控制——比如只唤醒“等库存”的线程,而不惊动“等订单确认”的线程。
为什么需要多个 Condition?
synchronized 块中只有一个隐式等待队列,notifyAll() 会唤醒所有等待线程,后续还得靠条件重检(while 循环判断),存在无效唤醒和资源浪费。而 ReentrantLock 支持绑定多个 Condition 实例,每个代表一个逻辑独立的等待队列,可按需精准 signal() 或 signalAll()。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
基本用法:一个锁 + 多个 Condition
关键步骤:
- 创建
ReentrantLock实例 - 调用
lock.newCondition()多次,得到不同语义的Condition对象(如notEmpty、notFull、orderConfirmed) - 线程在对应条件不满足时调用
condition.await()(自动释放锁并进入该 condition 的等待队列) - 当状态变更可能影响某类等待者时,调用对应
condition.signal()或signalAll()
典型示例:生产者-消费者中的双条件控制
模拟有界队列,区分“队列空”和“队列满”两种等待场景:
class BoundedQueue<t> {
private final ReentrantLock lock = new ReentrantLock();
private final Condition notEmpty = lock.newCondition(); // 消费者等待:非空
private final Condition notFull = lock.newCondition(); // 生产者等待:非满
private final Object[] items;
private int putIndex, takeIndex, count;
BoundedQueue(int capacity) {
this.items = new Object[capacity];
}
void put(T x) throws InterruptedException {
lock.lock();
try {
while (count == items.length) {
notFull.await(); // 等待“非满”,进入 notFull 队列
}
items[putIndex] = x;
if (++putIndex == items.length) putIndex = 0;
++count;
notEmpty.signal(); // 只唤醒一个等待“非空”的消费者
} finally {
lock.unlock();
}
}
T take() throws InterruptedException {
lock.lock();
try {
while (count == 0) {
notEmpty.await(); // 等待“非空”,进入 notEmpty 队列
}
@SuppressWarnings("unchecked")
T x = (T) items[takeIndex];
items[takeIndex] = null;
if (++takeIndex == items.length) takeIndex = 0;
--count;
notFull.signal(); // 只唤醒一个等待“非满”的生产者
} finally {
lock.unlock();
}
return x;
}
}</t>
进阶技巧与注意事项
-
await() 必须在 lock 保护下调用:否则抛
IllegalMonitorStateException - 总是用 while 而非 if 检查条件:防止虚假唤醒或信号丢失后条件仍不成立
- signal() 不立即抢锁:被唤醒线程需重新竞争锁,获得锁后才从 await 返回
- Condition 是绑定到锁的,不能跨锁复用:不同锁创建的 Condition 互不兼容
-
可为复杂业务建模多个 Condition:例如订单系统中可设
paymentReceived、warehouseReady、logisticsAssigned等,各角色线程只监听关心的条件
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










