ReentrantLock结合Condition可实现线程精确通信,通过newCondition()创建条件对象,await()使线程等待并释放锁,signal()/signalAll()唤醒等待线程,须在持有锁时调用且配合try-finally确保解锁。
在Java中,ReentrantLock 提供了比 synchronized 更灵活的锁机制,配合 Condition 可以实现线程间的精确等待与唤醒。相比 Object 的 wait/notify,Condition 允许创建多个等待队列,控制更精细。
使用 Condition 前,必须先获取 ReentrantLock 实例,并通过其 newCondition() 方法生成 Condition 对象。
private final ReentrantLock lock = new ReentrantLock(); private final Condition condition = lock.newCondition();
在线程需要等待某个条件满足时,调用 condition.await()。该方法会释放锁并使当前线程进入等待状态,直到被其他线程唤醒。
示例:消费者等待缓冲区非空
public void take() throws InterruptedException {
lock.lock();
try {
while (buffer.isEmpty()) {
condition.await(); // 释放锁并等待
}
buffer.remove();
} finally {
lock.unlock();
}
}
当条件发生变化时,
使用 condition.signal() 唤醒一个等待线程,或 signalAll() 唤醒所有等待线程。
示例:生产者放入数据后通知消费者
public void put(Object item) {
lock.lock();
try {
buffer.add(item);
condition.signal(); // 唤醒一个等待的消费者
} finally {
lock.unlock();
}
}
注意:调用 await、signal 等方法前必须持有对应的锁,否则会抛出 IllegalMonitorStateException。
基本上就这些。Condition 让你能在特定条件下挂起和恢复线程,适合实现阻塞队列、生产者-消费者模型等场景。关键是记得在 try-finally 中加锁解锁,避免死锁。