ReentrantLock 配合 Condition 可精准控制线程等待与唤醒,支持多生产者多消费者模型;一个 Lock 可绑定多个 Condition,分别对应“队列满”和“队列空”等不同等待条件,避免虚假唤醒,需用 while 循环判断、try-finally 保证锁释放。

ReentrantLock 配合 Condition 可以精准控制线程等待与唤醒,比 synchronized + wait/notify 更灵活,适合实现多生产者多消费者模型。
用 ReentrantLock 和 Condition 替代 synchronized
synchronized 无法区分不同等待条件(比如“队列满”和“队列空”),而 Condition 允许为每种业务逻辑创建独立的等待队列。一个 ReentrantLock 可绑定多个 Condition 实例,生产者等待“不满”,消费者等待“不空”,互不干扰。
关键点:
- Lock 必须显式 lock() 和 unlock(),建议用 try-finally 保证释放
- 每个 Condition 对应一类等待场景,调用 await() 进入等待,signal()/signalAll() 唤醒对应队列中的线程
- await() 会自动释放锁,被唤醒后需重新获取锁才能继续执行
定义共享缓冲区与两个 Condition
以阻塞队列为例,维护一个 List 和容量限制。声明两个 Condition:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
立即学习“Java免费学习笔记(深入)”;
- notFull:供生产者等待,当队列满时 await()
- notEmpty:供消费者等待,当队列空时 await()
代码片段示意:
private final Lock lock = new ReentrantLock(); private final Condition notEmpty = lock.newCondition(); private final Condition notFull = lock.newCondition(); private final List<String> buffer = new ArrayList<>(); private final int capacity = 10;
生产者逻辑:检查、添加、通知
生产者先获取锁,判断是否满;满则 await() 挂起;否则添加元素,并 signal() 消费者队列(因为可能有消费者在等)。
- 注意:用 while 而非 if 判断条件,防止虚假唤醒
- 添加完后调用 notEmpty.signal(),告诉至少一个消费者可以取了
- 不需要 signalAll,除非需要唤醒所有等待消费者(如广播场景)
消费者逻辑:检查、移除、通知
消费者同样先加锁,判断是否空;空则 await();否则取走元素,并 signal() 生产者队列。
- 移除操作推荐用 remove(0) 或 poll(),避免索引越界
- 消费完成后调用 notFull.signal(),让等待的生产者有机会继续生产
- signal() 和 await() 必须在 lock() 之后、unlock() 之前调用

















