reentrantlock 配合 condition 可替代 wait/notify,提供多等待队列、精准唤醒及更好安全性;需用 while 循环防虚假唤醒,且必须显式加锁/解锁并置于 finally 块中。

ReentrantLock 本身不能直接替代 wait/notify,但它配合 Condition 接口可以实现更灵活、更安全的线程协作,效果上等价甚至优于传统的 synchronized + wait/notify。
用 Condition 替代 wait/notify
ReentrantLock 通过 newCondition() 创建一个或多个 Condition 实例,每个 Condition 提供独立的 await() 和 signal()/signalAll() 方法,相当于为不同等待场景建立专属的“等待队列”。
-
await()类似于wait():释放锁、挂起当前线程,直到被 signal 或中断 -
signal()类似于notify():唤醒一个在该 Condition 上等待的线程 -
signalAll()类似于notifyAll():唤醒所有在该 Condition 上等待的线程
避免虚假唤醒,必须配合 while 循环检查条件
和 wait/notify 一样,await() 也可能被虚假唤醒(spurious wakeup),所以必须在循环中调用:
lock.lock();
try {
while (!conditionMet()) {
condition.await();
}
// 执行业务逻辑
} finally {
lock.unlock();
}
直接用 if 是不安全的,会导致线程跳过条件检查,引发状态不一致。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
支持多个等待队列,解耦不同等待逻辑
这是 ReentrantLock + Condition 的核心优势。例如生产者-消费者模型中,可分别定义:
-
notFullCondition:供生产者等待缓冲区有空位 -
notEmptyCondition:供消费者等待缓冲区非空
这样 signal() 可精准唤醒对应角色,避免 notifyAll 带来的无效唤醒和竞争。
注意锁的显式管理与异常安全
使用 ReentrantLock 必须手动加锁、解锁,且 unlock() 务必放在 finally 块中,否则可能造成死锁:
- 不要在 try 块外调用 lock(),也不要在未捕获异常时跳过 unlock()
- Condition 方法只能在持有对应 Lock 的前提下调用,否则抛出 IllegalMonitorStateException
- await() 会自动释放锁;被唤醒后重新获取锁才返回,保证临界区安全
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










