Condition类是ReentrantLock的一个内部条件类,用于根据条件唤醒线程和Notify以及NotifyAll一个作用. 下面直接开始看源码:
//内部维护者一个node双链表队列
public class ConditionObject implements Condition, java.io.Serializable {
private static final long serialVersionUID = 1173984872572414699L;
/** First node of condition queue. */
private transient Node firstWaiter;
/** Last node of condition queue. */
private transient Node lastWaiter;
/**
* Creates a new {@code ConditionObject} instance.
*/
public ConditionObject() { }
//新增一个条件等待节点
//1.判断为节点释放是已经取消的节点,如果是则调用unlinkCancelledWaiters 移除已经被取消的节点
//2.根据当前线程创建一个Node节点状态为CONDITION的节点
//3.然后把当前线程的条件节点添加到尾尾部,并且把节点设置为尾节点。
private Node addConditionWaiter() {
Node t = lastWaiter;
// If lastWaiter is cancelled, clean out.
if (t != null && t.waitStatus != Node.CONDITION) {
unlinkCancelledWaiters();
t = lastWaiter;
}
//构建节点
Node node = new Node(Thread.currentThread(), Node.CONDITION);
if (t == null)
firstWaiter = node;
else
t.nextWaiter = node;
lastWaiter = node;
return node;
}
//移除被取消的条件节点
//拿到头节点,然后通过遍历移除已经被取消的节点
private void unlinkCancelledWaiters() {
Node t = firstWaiter;
//记录临时尾节点
Node trail = null;
while (t != null) {
//拿到下一个节点
Node next = t.nextWaiter;
//判断当前节点释放被取消
if (t.waitStatus != Node.CONDITION) {
//把当前的下一个节点置空
t.nextWaiter = null;
//临时为节点等于null,则存放头节点中
if (trail == null)
firstWaiter = next;
else
//否则一路记录尾节点
trail.nextWaiter = next;
//最后把尾节点Ithaca成全局节点
if (next == null)
lastWaiter = trail;
}
else
trail = t;
t = next;
}
}
//自旋唤醒当个条件节点一直自旋到唤醒为止
private void doSignal(Node first) {
do {
if ( (firstWaiter = first.nextWaiter) == null)
lastWaiter = null;
first.nextWaiter = null;
} while (!transferForSignal(first) &&
(first = firstWaiter) != null);
}
//遍历每个条件队列的等待节点通过transferForSignal去一个个唤醒。
private void doSignalAll(Node first) {
lastWaiter = firstWaiter = null;
do {
Node next = first.nextWaiter;
first.nextWaiter = null;
transferForSignal(first);
first = next;
} while (first != null);
}
//AQS中的transferForSignal 唤醒条件队列里的节点
final boolean transferForSignal(Node node) {
//cas修改状态
if (!compareAndSetWaitStatus(node, Node.CONDITION, 0))
return false;
//进去判断释放初始化AQS等待节点
Node p = enq(node);
int ws = p.waitStatus;
//再次修改状态
if (ws > 0 || !compareAndSetWaitStatus(p, ws, Node.SIGNAL))
//通过lockSupport.unpark唤醒
LockSupport.unpark(node.thread);
return true;
}
//唤醒节点,signal首先唤醒的是头节点,然后调用dosignal进行唤醒操作
public final void signal() {
if (!isHeldExclusively())
throw new IllegalMonitorStateException();
Node first = firstWaiter;
if (first != null)
doSignal(first);
}
//唤醒条件队列里的所有节点。
public final void signalAll() {
if (!isHeldExclusively())
throw new IllegalMonitorStateException();
Node first = firstWaiter;
if (first != null)
doSignalAll(first);
}
//重新中断标记
private static final int REINTERRUPT = 1;
//退出等待是抛出异常状态
private static final int THROW_IE = -1;
private int checkInterruptWhileWaiting(Node node) {
return Thread.interrupted() ?
(transferAfterCancelledWait(node) ? THROW_IE : REINTERRUPT) :
0;
}
//根据不同的状态去中断线程
private void reportInterruptAfterWait(int interruptMode)
throws InterruptedException {
if (interruptMode == THROW_IE)
throw new InterruptedException();
else if (interruptMode == REINTERRUPT)
selfInterrupt();
}
//不可中断拿到释放锁,进入条件队列
public final void awaitUninterruptibly() {
//构建锁
Node node = addConditionWaiter();
int savedState = fullyRelease(node);
boolean interrupted = false;
while (!isOnSyncQueue(node)) {
LockSupport.park(this);
if (Thread.interrupted())
interrupted = true;
}
if (acquireQueued(node, savedState) || interrupted)
selfInterrupt();
}
//通过await调整释放锁的线程会生成一个node节点进入这个条件队列
public final void await() throws InterruptedException {
//释放被中断你,如果中断则抛出异常
if (Thread.interrupted())
throw new InterruptedException();
//增加一个条件等待节点
Node node = addConditionWaiter();
//把锁的持有者线程释放以及状态state修改
int savedState = fullyRelease(node);
int interruptMode = 0;
//判断同步队列里,如果只一个节点则不挂起,
//或者说该线程本来就在AQS的等待队列里则不用挂起
//如果不在则需要挂起来
while (!isOnSyncQueue(node)) {
LockSupport.park(this);
if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
break;
}
//调用AQS的唤醒其他等待节点的线程,并且如果只有一个自己一个节点则直接获取锁。
if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
interruptMode = REINTERRUPT;
//清楚以及被取消的节点
if (node.nextWaiter != null) // clean up if cancelled
unlinkCancelledWaiters();
if (interruptMode != 0)
reportInterruptAfterWait(interruptMode);
}
小结: 通过condition的await方法,会先构建一个条件节点,然后进行锁释放,判断当前条件队列的状态和节点释放已经存在AQS等待队列里如果存在则不用挂起
最后进行获取锁或者说唤醒AQS等待队列的其他节点,然后进行清理工作清楚已经被取消的节点
//AQS的方法判断队列里释放有该节点或者是
final boolean isOnSyncQueue(Node node) {
if (node.waitStatus == Node.CONDITION || node.prev == null)
return false;
if (node.next != null) // If has successor, it must be on queue
return true;
return findNodeFromTail(node);
}
//查找Conditino队列的接释放在AQS的等待队列里。
private boolean findNodeFromTail(Node node) {
Node t = tail;
for (;;) {
if (t == node)
return true;
if (t == null)
return false;
t = t.prev;
}
}
//AQS中的fullyRelease 该放方式是释放锁,包括重入锁的次数也全部释放完
final int fullyRelease(Node node) {
boolean failed = true;
try {
//拿到锁的状态
int savedState = getState();
//把重入的次数全部释放完
if (release(savedState)) {
failed = false;
return savedState;
} else {
throw new IllegalMonitorStateException();
}
} finally {
if (failed)
node.waitStatus = Node.CANCELLED;
}
}
final boolean isOwnedBy(AbstractQueuedSynchronizer sync) {
return sync == AbstractQueuedSynchronizer.this;
}
//判断释放有条件等待节点
protected final boolean hasWaiters() {
if (!isHeldExclusively())
throw new IllegalMonitorStateException();
for (Node w = firstWaiter; w != null; w = w.nextWaiter) {
if (w.waitStatus == Node.CONDITION)
return true;
}
return false;
}
//获取队列长度
protected final int getWaitQueueLength() {
if (!isHeldExclusively())
throw new IllegalMonitorStateException();
int n = 0;
for (Node w = firstWaiter; w != null; w = w.nextWaiter) {
if (w.waitStatus == Node.CONDITION)
++n;
}
return n;
}
//获取条件等待节点的线程
protected final Collection<Thread> getWaitingThreads() {
if (!isHeldExclusively())
throw new IllegalMonitorStateException();
ArrayList<Thread> list = new ArrayList<Thread>();
for (Node w = firstWaiter; w != null; w = w.nextWaiter) {
if (w.waitStatus == Node.CONDITION) {
Thread t = w.thread;
if (t != null)
list.add(t);
}
}
return list;
}
}