Java AtomicReferenceFieldUpdater

2020-01-03  本文已影响0人  南风nanfeng

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

仔细看过源码可以发现,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 并非毫无用处,相对原子类而言,有如下优点:

实例化

    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创建。

案例

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 实例 对字段的更新是原子的,以下场景下无法保证原子性:

上一篇 下一篇

猜你喜欢

热点阅读