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循环就能保证直到这一次累加成功