五、原子类

原子类

为什么要用原子类

  • 在volatile中提到,它是不能保证num++这种符合类操作的原子性问题。
  • 只能用锁机制去解决,但是原子类更精巧轻量,性能开销更小。

原理

CAS(Compare-and-Swap)

  • CAS包含三个操作数
    • 内存值 V
    • 预估值 A
    • 更新值 B

当且仅当V==A时,V讲被赋值为B,否则循环判断V是否与A相等

  • ABA问题
    • 同时用m、n线程同时取出值为A,然后n更新成B,然后又更新成A,这时候m线程一样可以更新成功!但是中间这个值已经被更新过两次
    • 如果链表的头在变化了两次后,恢复了原值,不代表链表就没有变化。

Atomic包主要提供四种原子更新方式

  1. 更新基本类型
    • AtomicInteger、AtomicBoolean、AtomicLong
  • AtomicInteger
public class AtomicInteger extends Number implements java.io.Serializable {
     private static final Unsafe unsafe = Unsafe.getUnsafe();
     
     public final int incrementAndGet() {
     //为什么返回的时候 要再一次+1?看下面这个方法的返回值就知道了
        return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
    }
}
    public final int getAndAddInt(Object var1, long var2, int var4) {
        int var5;
        do {
        //获取原来的值
            var5 = this.getIntVolatile(var1, var2);
        } while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));
//这里返回的是var5,也就是原来的值,更新后的值是var5+var4
        return var5;
    }
// 是一个native方法 
    public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5);
  1. 更新数组
  • AtomicIntegerArray
  • AtomicLongArray
  • AtomicReferenceArray
  1. 更新引用
  • AtomicReference
  • AtomicReferenceFieldUpdater 更新引用类型里的字段
  • AtomicMarkableReference 更新带有标记位的引用类型
  1. 更新字段
  • AtomicIntegeFieldUpdater
  • AtomicLongFieldUpdater
  • AtomicStampedReference 更新引用类型,带有版本号,解决ABA的问题。
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容