一》对于CAS的理解
要对CAS进行探究,我们先从AtomicInteger这个类的getAndIncrement()这个方法说起 ,这个方法主要可以解决volatile关键字不保证原子性的问题。下面我们进入这个方法中进行进行探究:
public final int getAndIncrement() {
return unsafe.getAndAddInt(this, valueOffset, 1);
}
进入getAndIncrement()这个方法,可以看到底层调用了Unsafe这个类对象的getAndAddInt()方法,再进入Unsafe这个类:
public final native boolean compareAndSwapObject(Object var1, long var2, Object var4, Object var5);
public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5);
public final native boolean compareAndSwapLong(Object var1, long var2, long var4, long var6);
public native Object getObjectVolatile(Object var1, long var2);
public native void putObjectVolatile(Object var1, long var2, Object var4);
Unsafe这个类来自JVM里rt.jar这个包,是JVM自身携带的一个类,可以看到里边的方法都是native关键字修饰的,说明Unsafe这个类的方法都是调用操作系统底层的资源来执行相应的任务的,类似于C语言中的指针操作内存。getAndIncrement()这个方法之所以能保证原子性,就是Unsafe这个类起到了作用。
再进入getAndAddInt(this, valueOffset, 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));//比较并交换
return var5;
}
这段代码就是CAS操作的核心,可以看到主要是通过循环来实现的,先来看看几个核心参数:
var1:表示当前的对象;
var2 :表示地址偏移量(Unsafe就是通过地址偏移量来获取数据的);
var5 :表示主物理内存中真实的共享变量的值;
var4+var5:表示变化量
首先通过var1和var2来获取