初识await方法
调用await方法后,执行流程:
- 判断线程是否中断,如果中断抛出异常
- 将当前线程放入condition链表中,并且删除链表中状态不是CONDITION的节点
- 释放所有的锁资源,并且返回重入的次数
- 如果当前线程不持有锁资源,抛出异常,并且将condition链表中的节点状态设置为CANCELLED
- 如果当前线程没有在AQS队列中,则挂起
public final void await() throws InterruptedException {
// 如果线程中断,则抛出中断异常
if (Thread.interrupted())
throw new InterruptedException();
// 将当前线程加入到condition单向链表中,并且删除链表中状态不是-2的节点
// 对单向链表做一次垃圾节点清理
Node node = addConditionWaiter();
// 释放所有锁资源,并且返回重入的次数
int savedState = fullyRelease(node);
int interruptMode = 0;
// 如果线程不在AQS队列中,则挂起。
// 有这样一种情况,线程在执行完fullyRelease方法后,时间片用完了,另一个线程拿到锁资源
// 并且另一个线程调用了signal方法,signal方法会将当前线程从condition队列中转移到AQS队列中。
// 此时,如果当前线程获得cpu资源继续执行,是不需要执行LockSupport.park(this)方法将其挂起的
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)
unlinkCancelledWaiters();
if (interruptMode != 0)
reportInterruptAfterWait(interruptMode);
}
private Node addConditionWaiter() {
Node t = lastWaiter;
// 如果尾节点不为空,并且尾节点的waitStatus值不为-2,说明节点不正常
if (t != null && t.waitStatus != Node.CONDITION) {
// 删除掉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;
}
// 释放所有的锁资源,并且返回重入次数
final int fullyRelease(Node node) {
boolean failed = true;
try {
int savedState = getState();
// release方法中传入state的值,表示释放所有锁资源
if (release(savedState)) {
failed = false;
return savedState;
} else {
// 当前线程没持有锁资源
throw new IllegalMonitorStateException();
}
} finally {
if (failed)
node.waitStatus = Node.CANCELLED;
}
}