Unsafe和CAS分别是什么

今天面试被问了CAS原理,我的回答是

数据做更改时会用一个递增的版本号判断数据是否发生过改变,如果已经发生过改变自旋直至到最新值然后变更;

这里有两个地方我一直理解错误:

1.版本号是自增的,所以我一直没理解为什么CAS会导致ABA问题

2.CAS会自旋直至最新值做更新,后来其实是AtomicInteger调用Unsafe做得事情(虽然之前有看过源码,但是被错误思想先入为主了)

// 代码1:AtomicInteger add方法
public final int getAndAdd(int delta) {
    return unsafe.getAndAddInt(this, valueOffset, delta);
}
// 代码2:add对应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;
}
// 代码3:AtomicInteger set方法
public final int getAndSet(int newValue) {
    return unsafe.getAndSetInt(this, valueOffset, newValue);
}
// 代码4:set对应Unsafe方法
public final int getAndAddInt(Object var1, long var2, int var4) {
    int var5;
    do {
        var5 = this.getIntVolatile(var1, var2);
        // this.compareAndSwapInt(var1, var2, var5, var5 + var4)
        // var1代表当前AtomicInteger实例对象
        // var2内存偏移量,简单理解为var1的内存地址,赋值代码是AtomicInteger static 代码块 具体见代码5
        // var5预期的旧值
        // var5 + var4 成功更改后的新值
    } while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));
    return var5;
}
// 代码5:Integer
private static final Unsafe unsafe = Unsafe.getUnsafe();
private static final long valueOffset;

static {
    try {
        valueOffset = unsafe.objectFieldOffset
            (AtomicInteger.class.getDeclaredField("value"));
    } catch (Exception ex) { throw new Error(ex); }
}

猜你喜欢

转载自www.cnblogs.com/zjack/p/11079950.html