CAS算法与Java原子类( 二 )

  • AtomicInteger原子更新 int 类型
  • AtomicLong原子更新 long 类型
  • 2. 引用类型
    • AtomicReference原子更新引用类型 , 通过泛型指定要操作的类
    • AtomicMarkableReference原子更新引用类型 , 内部维护一个 Pair 类型(静态内部类)的成员属性 , 其中有一个 boolean 类型的标志位 , 避免 ABA 问题
    • private static class Pair { final T reference; final boolean mark; private Pair(T reference, boolean mark) { this.reference = reference; this.mark = mark; } staticPair of(T reference, boolean mark) {return new Pair(reference, mark); }}private volatile Pair pair
    • AtomicStampedReference原子更新引用类型 , 内部维护一个 Pair 类型(静态内部类)的成员属性 , 其中有一个 int 类型的邮戳(版本号) , 避免 ABA 问题
    • private static class Pair { final T reference; final int stamp; private Pair(T reference, int stamp) { this.reference = reference; this.stamp = stamp; } staticPair of(T reference, int stamp) {return new Pair(reference, stamp); }}private volatile Pair pair
    3. 数组类型
    • AtomicIntegerArray原子更新 int 数组中的元素
    • AtomicLongArray原子更新 long 数组中的元素
    • AtomicReferenceArray原子更新 Object 数组中的元素
    4. 对象属性类型用于解决对象的属性的原子操作
    • AtomicIntegerFieldUpdater原子更新对象中的 int 类型字段
    • AtomicLongFieldUpdater原子更新对象中的 long 类型字段
    • AtomicReferenceFieldUpdater原子更新对象中的引用类型字段
    之前提到的三种类型的使用都比较简单 , 查阅对应 API 即可 , 而对象属性类型则有一些限制:
    • 字段必须是 volatile 类型的 , 在线程之间共享变量时保证立即可见
    • 只能是实例变量 , 不能是类变量 , 也就是说不能加 static 关键字
    • 只能是可修改变量 , 不能使用 final 变量
    • 该对象字段能够被直接操作 , 因为它是基于反射实现的
    5. 高性能原子类Java8 新增的原子类 , 使用分段的思想 , 把不同的线程 hash 到不同的段上去更新 , 最后再把这些段的值相加得到最终的值 。 以下四个类都继承自 Striped64 , 对并发的优化在 Striped64 中实现
    CAS算法与Java原子类文章插图
    • LongAccumulatorlong 类型的聚合器 , 需要传入一个 long 类型的二元操作 , 可以用来计算各种聚合操作 , 包括加乘等
    • LongAdderlong 类型的累加器 , LongAccumulator 的特例 , 只能用来计算加法 , 且从 0 开始计算
    • DoubleAccumulatordouble 类型的聚合器 , 需要传入一个 double 类型的二元操作 , 可以用来计算各种聚合操作 , 包括加乘等
    • DoubleAdderdouble 类型的累加器 , DoubleAccumulator 的特例 , 只能用来计算加法 , 且从 0 开始计算