Condition条件变量的使用与原理
请解释Condition在ReentrantLock中的作用、使用示例以及其底层实现原理(与AQS条件队列的关系)。
回答
孤独的心
Condition作用:
- 类似Object.wait/notify,但更灵活:一个ReentrantLock可创建多个Condition(如生产者-消费者模型中满/空两个条件)。
使用方法:
ReentrantLock lock = new ReentrantLock();
Condition notEmpty = lock.newCondition();
Condition notFull = lock.newCondition();
// 消费者
lock.lock();
try {
while (queue.isEmpty()) notEmpty.await();
queue.poll();
notFull.signal();
} finally { lock.unlock(); }
底层原理:
- ConditionObject是AQS的内部类,每个Condition维护一个条件等待队列(单向链表)。
- await():当前线程包装成Node加入条件队列,释放锁(完全释放重入次数),调用LockSupport.park()阻塞。
- signal():将条件队列的头节点转移到AQS的同步队列(CLH队列),等待获取锁。
- signalAll():将所有条件队列节点转移到同步队列。
与wait/notify区别:
- Condition支持多个等待集,Object.wait只有一个。
- Condition支持超时和中断(awaitUninterruptibly()/awaitNanos())。
- Condition的await()释放锁时会记录重入次数,被唤醒后恢复。