ReenTrantLcok Condition 原理笔记

参考:深入剖析基于并发AQS的(独占锁)重入锁(ReetrantLock)及其Condition实现原理
https://blog.****.net/javazejian/article/details/75043422

1.Condition节点
ReenTrantLcok Condition 原理笔记
waitStatues:等待队列中结点的状态只有两种即CANCELLED和CONDITION,前者表示线程已结束需要从等待队列中移除,后者表示条件结点等待被唤醒
thread:与此节点关联的线程
nextWaiter:下一个节点
一个ReenTranLock有多个Condition条件等待序列,但是只有一个同步队列(AQS队列)
2.await()方法
await()方法主要做了3件事,是调用addConditionWaiter()方法将当前线程封装成node结点加入等待队列是调用fullyRelease(node)方法释放同步状态并唤醒后继结点的线程。三是调用isOnSyncQueue(node)方法判断结点是否在同步队列中,注意是个while循环,如果同步队列中没有该结点就直接挂起该线程,需要明白的是如果线程被唤醒后就调用acquireQueued(node, savedState)执行自旋操作争取锁,即当前线程结点从等待队列转移到同步队列并开始努力获取锁。
ReenTrantLcok Condition 原理笔记
3.signal()方法
ReenTrantLcok Condition 原理笔记
看这张图,执行signal方法后,首先去找条件等待队列中的第一个节点,移除掉第一个节点,加入到同步队列中,加入到同步队列以后会去判断其前驱结点是否已结束或者设置前驱节点状态为Node.SIGNAL状态失败,则通过LockSupport.unpark()唤醒被通知节点代表的线程,这样signal()操作就完成了,完成以后说明这个节点已经是同步队列中的节点了,所以把await方法中的循环判断呢条件结束了,然后去执行自旋获取锁。