V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
amiwrong123
V2EX  ›  Java

为什么 AQS 里共享锁的释放里,不需要判断 head 后继节点是不是共享锁节点?

  •  
  •   amiwrong123 · 2020-06-08 00:05:36 +08:00 via Android · 1204 次点击
    这是一个创建于 1486 天前的主题,其中的信息可能已经有所发展或是发生改变。

    众所周知,AQS 通过调用releaseShared来释放共享锁,而它会调用到doReleaseShared

    public final boolean releaseShared(int arg) {
        if (tryReleaseShared(arg)) {
            doReleaseShared();
            return true;
        }
        return false;
    }
    

    而获得共享锁的线程,可能经过acquireShared(int arg) -> doAcquireShared(arg) -> 重复着阻塞和被唤醒(可能是这样) ->setHeadAndPropagate(node, r) -> doReleaseShared(),而它也会调用到doReleaseShared

        private void setHeadAndPropagate(Node node, int propagate) {
            Node h = head; 
            setHead(node);
            if (propagate > 0 || h == null || h.waitStatus < 0 ||
                (h = head) == null || h.waitStatus < 0) {
                Node s = node.next;
                if (s == null || s.isShared())
                    doReleaseShared();
            }
        }
    

    但获得共享锁的线程,是会判断 head 后继节点是否为共享锁节点的(if (s == null || s.isShared())),才会去调用 doReleaseShared 。

    但如果从释放共享锁的流程来看,根本不会判断 head 后继节点是否为共享锁节点的。然后就直接调动了 doReleaseShared:

    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);
                }
                else if (ws == 0 &&
                         !compareAndSetWaitStatus(h, 0, Node.PROPAGATE))
                    continue;                // loop on failed CAS
            }
            if (h == head)                   // loop if head changed
                break;
        }
    }
    

    当然,在 doReleaseShared 里,也不会在乎 head 后继是个啥,它都没有去看 head 后继是个啥。

    所以,为什么 AQS 里共享锁的释放里,不需要判断 head 后继节点是不是共享锁节点?

    目前尚无回复
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3042 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 75ms · UTC 00:38 · PVG 08:38 · LAX 17:38 · JFK 20:38
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.