Java AtomicReferenceFieldUpdater对象属性原子更新器

AtomicReferenceFieldUpdater出自java并发框架大神Doug Lea之手,这位哥基本承java.util.concurrent包的开发,让人佩服。本文来自查阅源码及注释的理解。
另外JUC提供3个原子更新器:

  • 1.AtomicIntegerFieldUpdater
  • 2.AtomicLongFieldUpdater
  • 3.AtomicReferenceFieldUpdater

仔细看过源码可以发现,AtomicInteger 和 AtomicIntegerFieldUpdater 的公共 API 几乎一模一样,所以在提供 CAS 操作这个层面,两者是几乎等价的。

该类用途

 * A reflection-based utility that enables atomic updates to
 * designated {@code volatile} reference fields of designated classes.  

简单来说,AtomicReferenceFieldUpdater能原子更新类中被volatile修饰的变量。
原理是通过反射实现对字段的原子更新。
那么问题来了,由于反射的性能较低,为什么不直接用 AtomicInteger,而要用 volatile + AtomicIntegerFieldUpdater 呢?
注释的解释是:

This class is designed for use in atomic data structures  
in which several reference fields of the same node are  
independently subject to atomic updates. 

这个类可以对多个属性原子更新,实际上AtomicInteger也支持。
当然 AtomicXFieldUpdater 并非毫无用处,相对原子类而言,有如下优点:

  • 1、AtomicX 毕竟是复杂类型,空间占用比 volatile 的原始类型要大,在超大数量的场景下,AtomicXFieldUpdater 在内存占用方面有优势;
  • 2、如果某个字段的 所有操作 都是原子操作,那可以用 AtomicX,但有的场景下,字段既需要原子操作,- - - 3、需要普通操作,这时可以考虑用 AtomicXFieldUpdater;
  • 4、如果要原子更新的字段在第三方类中,无法直接修改源码,则使用 AtomicXFieldUpdater;

实例化

    public static <U,W> AtomicReferenceFieldUpdater<U,W> newUpdater(Class<U> tclass,
                                                                    Class<W> vclass,
                                                                    String fieldName) {
        return new AtomicReferenceFieldUpdaterImpl<U,W>
            (tclass, vclass, fieldName, Reflection.getCallerClass());
    }

构造方法是空构造,访问权限是protected,表示外部包的类无法创建,正确姿势:调用静态方法newUpdater创建。

  • 第一个参数tclass表示引用类,持有属性的类。
  • 第二个参数vclass表示属性的类型。
  • 第三个参数fieldName表示属性的名称,能在类反射中找个这个属性。

案例

public class Node {
    private volatile Node left;
    private volatile Node right;

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

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

    public Node getLeft() {
        return left;
    }

    public boolean compareAndSetLeft(Node expect, Node update) {
        return leftUpdater.compareAndSet(this, expect, update);
    }
}

缺陷

 * <p>Note that the guarantees of the {@code compareAndSet}
 * method in this class are weaker than in other atomic classes.
 * Because this class cannot ensure that all uses of the field
 * are appropriate for purposes of atomic access, it can
 * guarantee atomicity only with respect to other invocations of
 * {@code compareAndSet} and {@code set} on the same updater.

即原子更新器的 CAS 比对应的原子类弱,只能保证通过 同一 updater 实例 对字段的更新是原子的,以下场景下无法保证原子性:

  • 1、同时使用多个 updater;
  • 2、除 updater 外,还使用(无并发处理的)普通更新操作;
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1.关于分数 从小学开始,爸爸妈妈对我就是这样要求的:只要学习态度好,考试考多少分都不会怪我,所以,我对考试分数没...
    米妮芳阅读 190评论 0 0
  • 每天习惯在做早餐时听樊登读书,今天竟然选择了回顾《高效能人士的七个习惯》,难道说是有心电感应吗 我...
    琦琦Shirley阅读 232评论 2 2
  • 花呗,我觉得每个人都很熟悉。即使你不用,你周围的人或多或少的也在用。然而,其中一些人却看不起用花呗的人,觉得这是一...
    商吕既朔阅读 293评论 1 2
  • 只有废物,才需要男朋友?你需要男朋友吗?需要,我愿意当个废物。 当我遇见他的时候,我正处在考研的压力期,父母却还是...
    浩浩汤汤吖阅读 454评论 0 5
  • 投射 继续睡好!玩得开心,看到美丽的风景,看到可爱的人和事。 感赏 今天打算去看一个不同的风景。本来打算去新都看看...
    妈妈随笔阅读 284评论 4 5