簡體   English   中英

JDK14 中的 AbstractQueuedSynchronizer 如何在使用 setPrevRelaxed 時確保內存可見性?

[英]How does AbstractQueuedSynchronizer in JDK14 ensure memory visibility when using setPrevRelaxed?

在方法acquirenode.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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM