更多关于AbstractQueuedSynchronizer介绍,请戳《JUC之AbstractQueuedSynchronizer基本介绍》、《JUC之AbstractQueuedSynchronizer共享模式》。
在AbstractQueuedSynchronizer中提供一个内部类ConditionObject用于模拟线程等待(wait)和唤醒(notify)的功能。ConditionObject中提供一个等待队列用于存放等待状态的线程,提供await方法用于将当前线程加入到等待队列中,提供signal方法用于唤醒线程将其从等待队列中移除。和Synchronized类比,await相当于Object中wait,signal相当于Object中notify,所以当前线程在使用await和signal方法的时候,也必须要持有AbstractQueuedSynchronizer提供的锁(通过acquire方法成功获取到锁)。
█ 等待队列
ConditionObject中也提供了一个等待队列,AbstractQueuedSynchronizer中的等待队列也可以叫同步队列,队列中的线程在等待获取锁。在ConditionObject的等待队列中的线程是先前已经获取到锁了,自己主动放弃锁进入等待队列,等待某个持有锁的线程将其唤醒或者自己主动唤醒(超时等待)。
private transient Node firstWaiter;
private transient Node lastWaiter;
通过firstWaiter指向等待队列中的第一个等待节点,lastWaiter指定等待队列中的最后一个节点。节点与节点之间通过前一个节点的nextWaiter指向下一个节点。所以不同于AbstractQueuedSynchronizer中的等待队列(同步队列)是双向的,ConditionObject中的等待队列是单向链表。这里的firstWaiter、lastWaiter与AbstractQueuedSynchronizer中的head、tail意思是一样的。
█ await
持有锁的线程调用await方法将会主动放弃锁,将其加入等待队列中。
public final void await() throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
// 将当前线程封装成node对象添加到等待队列中
Node node = addConditionWaiter();
int savedState = fullyRelease(node);
int interruptMode = 0;
while (!isOnSyncQueue(node)) {
LockSupport.park(this);
if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
break;
}
if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
interruptMode = REINTERRUPT;
if (node.nextWaiter != null) // clean up if cancelled
unlinkCancelledWaiters();