每天一点小知识—— Java中的CAS是什么?

714 阅读1分钟

Java中的CAS是什么?

  1. CAS,就是compareAndSwap,比较和替换

  2. 在Java中的实现,下面是AtomicInteger类中的部分实现,其它Atomic类同理

    public final int getAndIncrement() { return unsafe.getAndAddInt(this, valueOffset, 1); }

可以看到是调用了sun.misc.Unsafe这个类的getAndAddInt

//offset v在内存中的偏移地址
public final int getAndAddInt(Object o, long offset, int delta) {
        int v;
        do {
            v = getIntVolatile(o, offset);//这一句就是获取到当前的值
        } while (!compareAndSwapInt(o, offset, v, v + delta));//v + delta就是计算结果值作为参数
        return v;
}

compareAndSwapInt是一个native方法,这里不做深入,上面的代码流程图是这样的

可以看出,就是在一个while中不断拿当前内存中的值,然后进行计算,然后再次拿内存中的值和之前拿到的值相比较,如果一样就默认没有被别的线程修改过,更新为新的值result,如果不一样,说明内存中的值被修改了,重新再来一遍。这就是所谓的自旋。

缺点:
  1. 多线程竞争激烈的时候,可能会一直自旋,消耗CPU
  2. ABA问题:即A->B->A,就是在上图的步骤1到3之间,值从A被修改为B,然后又被修改为A,这时候执行到3的时候会判断值没有改变,其实已经改变过了,基本类型可能影响不大,引用类型由于有多个变量,就比较麻烦了。解决办法,加个操作版本号,例如AtomicStampedReference