为什么Java AQS队列向后遍历

时间:2019-11-12 13:30:09

标签: java concurrency

以下是道格·李(Doug Lea)的论文的参考文献:

  

AbstractQueuedSynchronizer队列节点包含指向其的下一个链接   接班人。但是因为没有适用的技术   使用以下命令无锁定地插入双链列表节点   compareAndSet,此链接不是自动设置为插入的一部分;   它只是简单地分配:pred.next = node;插入后。这是   反映在所有用法中。下一个链接仅被视为已优化   路径。如果节点的后继者似乎不存在(或似乎是   取消)通过其下一个字段,始终可以从   列表的尾部,然后使用pred字段向后遍历   准确检查是否确实存在。

这是Java 8源代码:

    private Node enq(final Node node) {
        for (;;) {
            Node t = tail;
            if (t == null) { // Must initialize
                if (compareAndSetHead(new Node()))
                    tail = head;
            } else {
                node.prev = t;
                if (compareAndSetTail(t, node)) {
                    t.next = node;
                    return t;
                }
            }
        }
    }

如果我将其更改为:

else {
    if (compareAndSetTail(t, node)) {
        t.next = node;
        node.pre = t;
        return t;
    }
}

1 个答案:

答案 0 :(得分:0)

在这种情况下,当线程进入If语句并被其他线程中断时,头节点从尾部开始遍历,甚至无法访问尾部节点的上一个节点。