ConditionObject的await方法分析
- 判断当前线程是否中断,中断直接抛出非法监视器状态异常
- 要是没有中断则通过addConditionWaiter()方法将该节点加入到Condition的单向链表中
- 通过fullyRelease(node)方法一次新释放掉锁资源
- 初始化一个状态模式为0的标记
- 执行while判断,要是线程不在AQS队列中就挂起该线程(要是在AQS队列中可能有一种情况那就是该线程刚释放锁资源,立刻就被唤醒,所以他会进入AQS队列自然不用去挂起他)
- 检查当前线程在获取锁资源的时候有没有被中断过
线程添加到Condition单项链表中的代码分析
- 获取尾节点
- 尾节点不为空,并且尾节点的状态值不为-2,那么就取消当前节点,并重新获取尾节点
- 创建新的节点,并将节点的状态值设置为-2.
- 如果当前节点是尾节点是null,直接将刚才创建的节点放置为第一个等待节点
- 否则就排在尾节点的后面
- 最后返回当前节点
分析后半部分await()代码的含义
- 判断当前线程的中断模式
- 解释三目运算符,要是线程没有被中断,返回0
- THROW_IE:中断唤醒
- REINTERRUPT:signal唤醒,并且线程在AQS队列中
- 此处存在一个细节就是Thread.interrupted()能查看当前线程状态并重置当前线程状态
- 下面这个方法要是返回true,则意味着线程时中断唤醒并且在AQS队列中,只有以上两个条件都满足才会返回true。
- 下面这个方法在singal也有一个一样的基于CAS的判断,要是能进来那么就说明是中断唤醒的线程
- 将当前节点添加到AQS队列
- 往后判断当前线程是否在AQS队列中,因为基于singal唤醒的线程可能不在AQS队列。
isOnSyncQueue(node)分析
- 判断当前node节点是否在AQS队列上
- 两个条件当前节点的状态为-2或者当前节点的前一个节点为空都是不在
- 要是节点的下一个节点不为空就在了,因为在Condition的单向链表中没有next这个指针
findNodeFromTail(node)队列中找到当前节点