[英]How does AbstractQueuedSynchronizer in JDK14 ensure memory visibility when using setPrevRelaxed?
在方法acquire
, node.prev
由更新node.setPrevRelaxed(t)
。
它實際上調用了不確保可見性的unsafe.putReference
。
final void setPrevRelaxed(Node p) { // for off-queue assignment
U.putReference(this, PREV, p);
}
它如何確保node.prev
的可見性?
在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
iff euqueue 在 Condition 對象中被調用,以確保該對象已獲得鎖。
另一個地方是在獲取方法中
...
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 成功后看到。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.