先来看一下这个Condition的使用场景,在LinkedBlockingQueue(链表的阻塞队列)类中包含如下的定义,通过使用lock.newCondition()方法,可以获得一个Condition对象,说明Condition与ReentrantLock有着重要的关联关系。

Condition对象创建
通常它们的使用方式是如下这样,注意线程1的condition.await()和线程2的condition.signal()方法,后面重点讲解这两个方法。

例子
Condition类是AQS(AbstractQueuedSynchronizer,抽象的队列同步器)的内部类,我们重点来看下这个线程1的condition.await()方法,对里面的几个重要方法进行重点的说明。

await()方法
Node node = addConditionWaiter();//将当前线程包装成Node,然后放入条件等待队列中,注意这个队列和//外面的ReentrantLock的同步等待队列是两个不同的队列,在唤醒时(也就是调用condition.signal()),会把//这个线程先从条件等待队列中移除,然后转移到ReentrantLock的同步等待队列里面去,然后在同步等待队列//中获取锁以后,才能真正的被执行int savedState = fullyRelease(node);//在将当前线程放入到条件等待队列中以后,这个方法会把当前线程//所持有的锁释放掉,这个时候ReentrantLock同步等待队列中的某一个线程会获得锁,然后被激活int interruptMode = 0;while (!isOnSyncQueue(node)) {//判断当前线程如果不存在于ReentrantLock同步队列中,则将当前线程//中断挂起,如果这个线程存在于ReentrantLock同步队列中,那么它已经被中断挂起,则不需要再次中断挂起 LockSupport.park(this);
总结来说就是,将当前线程封装成Node,然后加入到条件等待队列中,释放线程持有的锁,然后将此线程中断挂起。
接下来我们重点来看下线程2的condition.signal()方法,对里面的几个重要方法进行重点的说明。

signal()方法
if (!isHeldExclusively())//判断此线程是不是ReentrantLock锁的独占线程,如果不是则抛出异常,换言之//只有是ReentrantLock锁的独占线程,才能进行唤醒操作,也就是说在执行condition.await()//和condition.signal()方法时,线程必须拿到ReentrantLock锁才可以进行,这也就是Condition //与ReentrantLock有着必要的关联关系 throw new IllegalMonitorStateException(); Node first = firstWaiter;//拿到条件等待线程的第一个Node if (first != null) doSignal(first);//第一个Node不为null时,进行唤醒操作
下面来看下doSignal(first)方法的执行逻辑,重点看下其中的transferForSignal(first)方法。

doSignal()方法

transferForSignal()方法
if (!compareAndSetWaitStatus(node, Node.CONDITION, 0))//将Node的节点更新为0,如果更新失败, //则代表此节点已经被取消了,直接返回失败,遍历下一个条件等待队列的节点。 return false;Node p = enq(node);//重点方法,将当前节点由条件等待队列转移到ReentrantLock的同步等待队列的队尾中去 int ws = p.waitStatus;//此时被转移到同步等待队列的Node的waitStatus应该是0, if (ws > 0 || !compareAndSetWaitStatus(p, ws, Node.SIGNAL))//将此Node节点的waitStatus更新为-1 LockSupport.unpark(node.thread);//此逻辑不会执行,因为线程从条件等待队列只是被转移到了同步 //等待队列,而且是队尾的位置,如果同步等待队列前面有有其他线程,则会优先于它被唤醒。 return true;
在执行了condition.signal()方法后,会将条件等待队列中的线程移除,然后转移到ReentrantLock的同步等待队列中,后面的逻辑就和ReentrantLock(可重入锁)执行同步等待队列中的线程一样了(这个逻辑不清楚可以查看我的此篇文章(原创)Java的ReentrantLock(可重入锁)详解上篇)。
简单总结下,Condition依赖于ReentrantLock,必须拿到ReentrantLock锁以后,才可以进行await()和single()方法,在执行了await()时,会释放持有的ReentrantLock锁,并把自己加入到条件等待队列中去,在执行了single()时,会把线程从条件等待队列转移到ReentrantLock的同步等待队列中去,然后等待被真正的执行。