heima并发---并发工具包(3)---条件变量--245
每个条件变量对应一个conditionObject这个对象,这个对象在sync里面的,内部也是维护了一个双向链表的。
await流程和signal流程。
这个方法就是线程加入到条件变量的双向链表里面去。
都是假如到队列的尾部的。
可知:
接下来:
这个方法是当前的节点就是thread-0节点上的所有锁都释放掉,和wait是一样的,包括锁重入的次数。
唤醒等待队列的离头节点最近的下一个节点,竞争。
接下来进入park状态,等待被唤醒。
while循环我们不管它。
---245---
signal方法:
首先检查调用signal的方法是不是锁的持有者,不是就直接抛出异常。
找条件变量等待队列里面的头的元素,不为空就调用doSignal方法。
注意:链表有多个元素的话也不是随机的去调用,总是调用队首的元素。
进入doSingnal方法:
这个方法主要是使节点在条件变量这个链表断开,重新竞争锁,加入到等待锁的这个链表中。
第一个waiter=第一个waiter的nextWaiter。
指向null,在条件变量这个链表中断开。
进入这个方法:
节点转移到竞争锁的链表,就是等待队列的。转移失败的话唤醒下一个节点。
为什么会转移失败呢?可能会被打断或者取消的。
这里为什么改为0。因为加入到条件变量这个链表中这个状态就变成了-2了。加入到锁的竞争队列里面,总是为0。
进入到这个方法:
进入:
将节点加入到等待队列的尾部。成功了返回前驱节点。
检查前驱节点的状态。改为-1,有责任唤醒链表的下一个元素。
流程分析:
源码解析:
---246---