JUC - Condition 源码分析
Condition将Object监视器方法(wait、notify 和 notifyAll)分解成截然不同的对象,以便通过将这些对象与任意Lock实现组合使用,为每个对象提供多个等待set(wait-set)。其中,Lock替代了synchronized方法和语句的使用,Condition替代了Object监视器方法的使用。Condition实例实质上被绑定到一个锁上。要为特定Lock实例获得Condition实例,请使用其newCondition()方法。
源码分析
Condition属于AbstractQueuedSynchronizer(详见:JUC - AbstractQueuedSynchronizer(AQS) 源码分析)的一部分,AQS内部实现了一个实现Condition接口的内部类。
AQS维护了一个申请获取锁的同步队列(pred,next连接的双向队列),Condition维护了一个等待队列(nextWaiter连接的单向队列),一个AQS可以伴有多个Condition。当线程A获取到锁,然后调用await方法时,会将当前线程A加入到等待队列中并释放锁并挂起线程A;当线程B获取到锁,然后调用signal方法,将等待队列中的线程A转移到同步队列中,在同步队列中等待被唤醒,唤醒由释放锁的同时唤醒后继节点触发,线程A被唤醒后,将调用AQS的acquireQueued方法,直到获取到锁,线程A才从await方法返回。
*void await() throws InterruptedException
造成当前线程在接到信号或被中断之前一直处于等待状态。
|
|
Condition中的方法:
|
|
AQS中的方法:
|
|
*void awaitUninterruptibly()
造成当前线程在接到信号之前一直处于等待状态。
|
|
*long awaitNanos(long nanosTimeout) throws InterruptedException
造成当前线程在接到信号、被中断或到达指定等待时间之前一直处于等待状态。
|
|
*boolean await(long time, TimeUnit unit) throws InterruptedException
造成当前线程在接到信号、被中断或到达指定等待时间之前一直处于等待状态。此方法在行为上等效于:awaitNanos(unit.toNanos(time)) > 0
|
|
*boolean awaitUntil(Date deadline) throws InterruptedException
造成当前线程在接到信号、被中断或到达指定最后期限之前一直处于等待状态。
|
|
*void signal()
唤醒一个等待线程。
|
|
|
|
*void signalAll()
唤醒所有等待线程。
|
|
|
|
使用方式
BoundedBuffer是使用两个Condition维护的一个阻塞队列,队列空时,take方法会等待直到队列中有新元素加入;队列满时,put方法会等待直到队列中有元素移出。
|
|