JUC-AQS-Condition源码详解
如果直接看这个有难度,大家可以看下基础的AQS详解 JUC(一)-AQS源码分析
一、Condition的作用
二、Condition的数据结构
三、核心源码解读
3.1 await()
public final void await() throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
Node node = addConditionWaiter();
//放弃所有持有的锁
int savedState = fullyRelease(node);
int interruptMode = 0;
//阻塞判断,当前node是不是在同步队列时,不在同步队列那么就park当前线程
while (!isOnSyncQueue(node)) {
LockSupport.park(this);
//如果被中断了,则检测中断
if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
break;
}
//这是此节点已经在同步队列中了
//在队列中获取锁,并判断当前的interruptMode不为-1,即不是抛出异常
if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
//把中断类型设置为,重新中断,意味在线程获得锁的时候,重新中断线程
interruptMode = REINTERRUPT;
if (node.nextWaiter != null) // clean up if cancelled
unlinkCancelledWaiters();
if (interruptMode != 0)
reportInterruptAfterWait(interruptMode);
}
1.先判断当前线程的中断状态,如果为中断则抛出异常
2.如果不是中断状态,则把当前节点加入Condition队列中,即我们的等待队列中
3.释放当前持有的锁,并记住当前state的值
4.会阻塞在判断当前节点是否在同步队列中,只有当执行了signal(),节点才会被添加回到同步队列中,如果不在队列中,则park当前线程
5.如果在同步队列中,则尝试从队列中获得锁
6.获得锁之后,需要响应不同的中断模式
/**
* 判断是否要抛出中断异常
*/
private void reportInterruptAfterWait(int interruptMode)
throws InterruptedException