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  AtomicReferenceFieldUpdater newUpdater(Class tclass,
                                                                    Class vclass,
                                                                    String fieldName) {
        return new AtomicReferenceFieldUpdaterImpl
            (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 leftUpdater =
            AtomicReferenceFieldUpdater.newUpdater(Node.class, Node.class, "left");

    private static final AtomicReferenceFieldUpdater 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);
    }
}

缺陷

 * 

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 外,还使用(无并发处理的)普通更新操作;

你可能感兴趣的:(Java AtomicReferenceFieldUpdater对象属性原子更新器)