在方法acquire中,node.prev由node.setPrevRelaxed(t)更新。
它实际上调用了unsafe.putReference,它不确保可见性。
final void setPrevRelaxed(Node p) { // for off-queue assignment
U.putReference(this, PREV, p);
}它如何保证node.prev的能见度?
发布于 2021-12-19 11:26:34
在Java中,语义之前发生的事件确保了可见性。
例如,node.setPrevRelaxed(t)在两处使用,第一处在enqueue方法中。
final void enqueue(Node node) {
if (node != null) {
for (;;) {
Node t = tail;
node.setPrevRelaxed(t); // avoid unnecessary fence
if (t == null) // initialize
tryInitializeHead();
else if (casTail(t, node)) {
t.next = node;
if (t.status < 0) // wake up to clean link
LockSupport.unpark(node.waiter);
break;
}
}
}
}node != null当且仅当队列是在条件对象中调用,以确保该对象获得了一个锁。
另一个地方是获取方法。
...
node.waiter = current;
Node t = tail;
node.setPrevRelaxed(t); // avoid unnecessary fence
if (t == null)
tryInitializeHead();
else if (!casTail(t, node))
node.setPrevRelaxed(null); // back out
else
t.next = node;
...在这两种情况下,node.prev将在锁被释放或casTail成功释放后出现。
https://stackoverflow.com/questions/68770197
复制相似问题