reentrantlock 通过 condition 实现等待唤醒机制,需先加锁再调用 condition.await() 释放锁并挂起线程;必须用 lock.newcondition() 创建 condition;await 必须在持锁下调用且需循环检测条件;唤醒须配合 signal()/signalall() 且同样需持锁。

ReentrantLock 本身不提供 await() 方法,condition.await() 是通过它关联的 Condition 对象调用的。要让线程进入等待状态,必须先获取锁、再获取 Condition、再调用 await —— 这三步缺一不可,且 await 会自动释放当前持有的锁,并将线程挂起。
1. 创建 Condition 实例
一个 ReentrantLock 可以创建多个独立的 Condition,每个 Condition 管理一组等待线程:
- 通过
lock.newCondition()获取 Condition 对象(不能 new,也不能复用其他锁的 Condition) - 通常把 Condition 声明为成员变量,避免每次重复创建
- 例如:private final Condition notEmpty = lock.newCondition();
2. 正确使用 await 的流程
await 必须在已持有对应 ReentrantLock 的前提下调用,否则抛出 IllegalMonitorStateException:
- 先调用
lock.lock()获取锁 - 在
try块中检查条件(比如队列是否为空),不满足才 await - 调用
condition.await()—— 此时会原子性地释放锁、挂起线程 - 被唤醒后(signal 或中断),线程重新竞争锁,获得锁后从 await 返回,继续执行 try 块后续逻辑
3. 配套唤醒操作不能少
仅 await 不会让线程自然醒来,必须有其他线程调用 signal() 或 signalAll():
-
signal()唤醒一个等待该 Condition 的线程(具体哪个由 JVM 决定) -
signalAll()唤醒所有等待该 Condition 的线程 - 唤醒操作也必须在持有同一把锁的前提下进行(通常放在修改共享状态之后、unlock 之前)
4. 注意中断与虚假唤醒
await 可能因中断或虚假唤醒提前返回,所以必须在循环中检查条件:
- 不要写成
if (conditionNotMet) condition.await(); - 应写成
while (!conditionMet) condition.await(); - 若需响应中断,可用
awaitNanos、awaitUntil或捕获InterruptedException
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











