以下是道格·李(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;
}
}
答案 0 :(得分:0)
在这种情况下,当线程进入If语句并被其他线程中断时,头节点从尾部开始遍历,甚至无法访问尾部节点的上一个节点。