AQS.doReleaseShared

您所在的位置:网站首页 独占独占什么头 AQS.doReleaseShared

AQS.doReleaseShared

2023-07-18 03:40| 来源: 网络整理| 查看: 265

共享锁的释放和独占锁的释放有一定的差别

前面唤醒锁的逻辑和独占锁是一样,先判断头结点是不是SIGNAL状态,如果是,则修改为0,并且唤醒头结点的下一个节点

PROPAGATE: 标识为PROPAGATE状态的节点,是共享锁模式下的节点状态,处于这个状态下的节点,会对线程的唤醒进行传播

private void doReleaseShared() { for (;;) { Node h = head; if (h != null && h != tail) { int ws = h.waitStatus; if (ws == Node.SIGNAL) { if (!compareAndSetWaitStatus(h, Node.SIGNAL, 0)) continue; // loop to recheck cases unparkSuccessor(h); } // 这个 CAS 失败的场景是:执行到这里的时候,刚好有一个节点入队,入队会将这个 ws 设置为 -1 else if (ws == 0 && !compareAndSetWaitStatus(h, 0, Node.PROPAGATE)) continue; // loop on failed CAS } // 如果到这里的时候,前面唤醒的线程已经占领了 head,那么再循环 // 通过检查头节点是否改变了,如果 改变了就继续循环 if (h == head) // loop if head changed break; } }

h == head:说明头节点还没有被刚刚用 unparkSuccessor 唤醒的线程(这里可以理解为 ThreadB)占有,此时 break 退出循环。

h != head:头节点被刚刚唤醒的线程(这里可以理解为 ThreadB)占有,那么这里重新进入下一轮循环,唤醒下一个节点(这里是 ThreadB )。我们知道,等到 ThreadB 被唤醒后,其实是会主动唤醒 ThreadC...

 



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3