AtomicReference vs AtomicReferenceFieldUpdater,AtomicReferenceFieldUpdater 的目的是什么?

Net*_*ire 5 java reflection multithreading reference atomic

我想以原子方式升级我的参考。例如使用compareAndSet,getAndSet和其他原子操作。

我来自 C++,所以在 C++ 中我有volatile关键字和不同的原子内在函数,或者<atomic> API。在java中,还有一个volatile关键字和不同的不安全原子操作

顺便说一下,还有一个文档齐全的AtomicReference(以及Long, Integer, Boolean),因此JDK创建者为我们提供了一种安全地对引用和原语执行原子操作的方法。API 没有任何问题,它很丰富,而且看起来很熟悉。

但是,还有一个AtomicReferenceFieldUpdater wick 提供了一种执行原子操作的奇怪方式:您必须通过名称通过反射“找到”字段,然后您可以使用完全相同的操作。

所以我的问题是:

  1. 这样做的目的是AtomicReferenceFieldUpdater什么?在我看来,这是隐含的并且有点奇怪:您需要声明一个 volatile 变量字段AND和字段更新程序本身。那么我应该在哪里使用FieldUpdater?
  2. 它提供了一种间接方式:您正在 操纵(而不是更改!)FieldUpdater,而不是变量,这令人困惑。
  3. 性能:据我所知,无论是AtomicReferenceFieldUpdaterAtomicReference被委托给不安全,所以其性能基本相近,但无论如何:是否有任何性能损失 FieldUpdater安剑铮,卓杰参考?

孙兴斌*_*孙兴斌 12

它用于节省内存。

文档中的示例

class Node {
   private volatile Node left, right;

   private static final AtomicReferenceFieldUpdater<Node, Node> leftUpdater =
     AtomicReferenceFieldUpdater.newUpdater(Node.class, Node.class, "left");
   private static AtomicReferenceFieldUpdater<Node, Node> rightUpdater =
     AtomicReferenceFieldUpdater.newUpdater(Node.class, Node.class, "right");

   Node getLeft() { return left; }
   boolean compareAndSetLeft(Node expect, Node update) {
     return leftUpdater.compareAndSet(this, expect, update);
   }
   // ... and so on
 }
Run Code Online (Sandbox Code Playgroud)

它直接声明leftright作为Node。并且AtomicReferenceFieldUpdaterstatic final

如果没有AtomicReferenceFieldUpdater,您可能需要将它们声明为AtomicReference<Node>.

private  AtomicReference<Node> left, right;
Run Code Online (Sandbox Code Playgroud)

消耗的内存比Node. 当 有很多实例时Node,它比第一种方法消耗更多的内存。