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