Atomic累加原理

Atomic是如何保证累加的原子性。翻阅过源码的都晓得里面是使用unsafe这个魔术类,Unsafe提供的API大致可分为内存操作、CAS、Class相关、对象操作、线程调度、系统信息获取、内存屏障、数组操作等几类。
今天重点在讲他的cas

什么是CAS?

即比较并替换,实现并发算法时常用到的一种技术。CAS操作包含三个操作数——内存位置、预期原值及新值。执行CAS操作的时候,将内存位置的值与预期原值比较,如果相匹配,那么处理器会自动将该位置值更新为新值,否则,处理器不做任何操作。我们都知道,CAS是一条CPU的原子指令(cmpxchg指令),不会造成所谓的数据不一致问题,Unsafe提供的CAS方法(如compareAndSwapXXX)底层实现即为CPU指令cmpxchg。

atomic的累加如何实现原子性

通过cas我们能保证设值值的原子性

AtomicLong源代码


    /**
     * Atomically increments by one the current value.
     *
     * @return the updated value
     */
    public final long incrementAndGet() {
        return unsafe.getAndAddLong(this, valueOffset, 1L) + 1L;
    }

如上所示他是使用了unsafe的getAndAddLong进行直接加1,那我们接着看getAndAddLong源代码

unsafe源码

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));

        return var5;
    }

如上代码所示,他是通过了一个while的循环一直进行cas,直到他在原来的value上累加成功了一次,才会退出循环。因为很有可能在你cas的时候,别人已经进行过一次累加,导致你的期望值发生的变动于是cas失败,导致累加失败,而这个while循环就能保证直到这一次累加成功