bigywater.tech
Java 内部原理 · 137

Lock+Condition真实验证:同一把锁开两个Condition,signal真实只唤醒对应的那一组

synchronized+wait/notify只有一个"等待池",唤醒粒度粗;Lock+Condition可以从同一把锁上分裂出多个独立的等待队列——这篇真实创建两个Condition,验证signalAll()是否真的做到了精确唤醒。

真实精确唤醒,互不干扰
真实验证:notEmpty.signalAll()后,notEmpty组5个线程全部被唤醒,notFull组真实0个被唤醒
同样要求真实持锁
真实验证:未持有锁时调用Condition.await(),真实抛出IllegalMonitorStateException,和wait()规则一致

上一篇:ThreadLocalRandom真实验证

真实验证:两个Condition的signalAll()真实互不干扰

用同一个ReentrantLock创建notEmpty和notFull两个Condition,各自挂起5个线程在await(),然后只signalAll()其中一个。

LockConditionDemo.java Lock lock = new ReentrantLock(); Condition notEmpty = lock.newCondition(); Condition notFull = lock.newCondition(); // 5个线程await(notEmpty), 另5个线程await(notFull) notEmpty.signalAll(); // 只唤醒notEmpty这一组
真实实测
真实signalAll(notEmpty)后: notEmpty真实被唤醒数=5, notFull真实被唤醒数=0 (应该只有notEmpty组被唤醒)
真实signalAll(notFull)后: notFull真实被唤醒数=5

真实结果证明notEmpty.signalAll()精确地只唤醒了等待在notEmpty这个Condition上的5个线程,另外5个等待在notFull上的线程真实一个都没被惊动,被唤醒数精确为0。这正是Lock+Condition相比synchronized+wait/notify最核心的改进——传统的notify/notifyAll只能对整个对象的monitor操作,一个对象上所有wait()的线程都在同一个等待池里,没有办法区分"生产者在等的"和"消费者在等的";而Condition允许从同一把锁上真实切出多个逻辑独立的等待队列,让精确唤醒(只叫醒真正需要被叫醒的那一组)成为可能,这在经典的生产者-消费者模型(用notEmpty和notFull分别控制"队列不空"和"队列不满"两种等待条件)里非常关键。

真实验证:Condition.await()同样要求持有对应的锁

LockConditionDemo.java notEmpty.await(); // 在没有lock.lock()的情况下直接调用
真实实测
真实在未持有锁时调用Condition.await() 抛出: java.lang.IllegalMonitorStateException
Condition的设计真实完整保留了synchronized+wait/notify的"必须持锁"这条铁律,只是把等待队列做了拆分。真实结果证明,即使Condition用的不是synchronized关键字而是显式的Lock接口,调用await()之前依然必须先lock.lock()获得锁,否则真实抛出和Object.wait()完全一样的IllegalMonitorStateException。这背后的原理也是一致的:await()内部真实需要先释放锁、把线程放入等待队列,再在被唤醒后重新竞争锁——如果调用者根本没持有锁,这个"释放"操作本身就是非法的。Condition只是把"一个锁只能对应一个等待队列"这个限制解除了,而不是放松了加锁纪律,这也是为什么ReentrantLock配合多个Condition常被称为"更精细粒度的wait/notify",而不是一套全新的同步机制。

分步演示:生产者消费者是怎么真实通过 Condition 精确协作的

每一行都是真实运行这段代码得到的结果(用CountDownLatch控制观测时机)。

一把ReentrantLock真实能创建出多个独立的Condition,分别对应不同的等待条件——这是普通synchronized/wait/notify(每个对象只有一个隐式条件)做不到的
这一步新验证的协作状态

    参考与说明

    • 本文全部结果均在本机真实运行 Java 17 得到,精确唤醒计数和IllegalMonitorStateException重复运行完全一致。
    • 和notify与notifyAll真实验证一起看,能更完整理解从synchronized的单等待池到Lock+Condition多等待队列,这套并发原语在精细化控制上的真实演进。
    • 没有涉及:Condition.awaitUninterruptibly()和普通await()在真实响应中断上的差异、用Condition真实实现一个有界阻塞队列(结合notEmpty/notFull完整复刻ArrayBlockingQueue的核心逻辑)——这两个话题留给系列后面按需再写。
    京ICP备2026067502号-1京公网安备11010502063487号