await整体流程
await 流程
步骤一.进入等待队列
一开始 Thread-0 持有锁,调用 await方法,进入ConditionObject的addConditionWaiter流程:
创建状态为Node.CONDITION=-2的新Node,并关联 Thread-0,然后加入等待队列尾部。
步骤二.解锁释放所有的锁
接下来进入 AQS 的 fullyRelease 流程,因为执行await方法需要释放锁。释放同步器上所有的锁,因为是await,有可能有锁重入,所以叫fullyRelease 。
这里也体现了为什么await方法必须要持有锁才能调用,因为不持有锁就没法释放锁。
此时在lock中占有锁的线程Thread-0的持有者owner被置为null。
步骤三.unpark同步队列中下一个节点node
unpark AQS 队列中头结点的下一个节点,竞争锁,假设没有其他竞争线程,那么 Thread-1 竞争成功。
步骤四:自己在等待队列阻塞
Thread-0 一直park被阻塞。
signal 流程
步骤一.唤醒阻塞在等待队列的节点
假设 Thread-1 要来唤醒 Thread-0
步骤二.从等待队列出列
进入 ConditionObject 的 doSignal 流程,取得等待队列中第一个 Node,即 Thread-0 所在 Node
步骤三.进入同步队列
执行 transferForSignal 流程,将该 Node 加入 AQS 队列尾部,将 Thread-0 的 waitStatus 改为 0,Thread-3的waitStatus 改为 -1,有可能会失败,原因是被打断了 这时就不会加入等待链表。