Unsafe类
Unsafe是CAS的核心类,由于Java方法无法直接访问底层系统,需要通过本地(Native)方法来访问,Unsafe相当于一个后门的指针,基于该类可以直接操作特定的内存数据
变量valueOffset
表示该变量值在内存中的偏移地址,因为Unsafe就是根据内存偏移地址获取数据的
变量value用volatile修饰
保证了多线程之间的内存可见性
主函数中
AtomicInteger atomicInteger = new AtomicInteger(1);
atomicInteger.compareAndSet(1,2);
源码中
compareAndSet下调用unsafe类的compareAndSwapInt方法
public final boolean compareAndSet(int expect, int update) {
//参数依次是,当前对象,偏移量,期待值,更新值
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}
对应的函数原型是native方法
public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5);
AtomicInteger类中有静态方法
// setup to use Unsafe.compareAndSwapInt for updates
private static final Unsafe unsafe = Unsafe.getUnsafe();
private static final long valueOffset;// 注意是静态的
static {
try {
//偏移量
valueOffset = unsafe.objectFieldOffset
(AtomicInteger.class.getDeclaredField("value"));// 反射出value属性,获取其在内存中的位置
} catch (Exception ex) { throw new Error(ex); }
}
通过偏移量valueOffset(即下面的var2)调用getObjectVolatile获取对象在内存的位置
public final Object getAndSetObject(Object var1, long var2, Object var4) {
Object var5;
do {
//var5获取内存中的值,var1是this,var2是偏移量
var5 = this.getObjectVolatile(var1, var2);
} while(!this.compareAndSwapObject(var1, var2, var5, var4));
return var5;
}
对应的函数原型是native方法
public final native boolean compareAndSwapObject(Object var1, long var2, Object var4, Object var5);
val1:AtomicInteger对象本身
var2:该对象值得引用地址
var4:需要变动的数量
var5:用var1和var2找到的内存中的真实值
- 用该对象当前的值与var5比较
- 如果相同,更新 var4 并返回true
- 如果不同,继续取值然后再比较,直到更新完成
每个线程非阻塞,进入do-while循环中,不断的获取内存中偏移量相同的值,判断是否为最新,然后在进行更新操作,提高了并发性,也能够实现一致性。