首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在使用AbstractQueuedSynchronizer时,JDK14中的setPrevRelaxed是如何确保内存可见性的?

在使用AbstractQueuedSynchronizer时,JDK14中的setPrevRelaxed是如何确保内存可见性的?
EN

Stack Overflow用户
提问于 2021-08-13 09:51:30
回答 1查看 70关注 0票数 1

在方法acquire中,node.prevnode.setPrevRelaxed(t)更新。

它实际上调用了unsafe.putReference,它不确保可见性。

代码语言:javascript
复制
final void setPrevRelaxed(Node p) {      // for off-queue assignment
   U.putReference(this, PREV, p);
}

它如何保证node.prev的能见度?

EN

回答 1

Stack Overflow用户

发布于 2021-12-19 11:26:34

在Java中,语义之前发生的事件确保了可见性。

例如,node.setPrevRelaxed(t)在两处使用,第一处在enqueue方法中。

代码语言:javascript
复制
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当且仅当队列是在条件对象中调用,以确保该对象获得了一个锁。

另一个地方是获取方法。

代码语言:javascript
复制
...
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成功释放后出现。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68770197

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档