java原子类中CAS的使用

在多线程下,i++;操作不具有原子性,反汇编后i++由三步组成:取值,加操作,赋值.多线程造成累加不准确.
JUC包中原子类如何保证多线程下数据累加的准确性呢?

原子类原子操作的原理

  1. 首先,原子类中value属性通过volatile修饰,保证多线程间value的变化对其他线程是可见的;
  2. 其次,原子类中通过unsafe类获取value属性对应的内存偏移地址,即valueOffset
  3. 以AtomicInteger类的getAndSet方法举例,底层调用unsafe.getAndSetInt()
  4. 获取传入的实例this在valueOffset地址对应的值,即value属性的值,使用var5暂存,调用本地方法compareAndSwapInt(),通过this + valueOffset始终可以获取最新的value属性值,将value与var5对比,一致则将value值设置为 newValue,不一致则重新获取
  5. 原子类通过上述步骤避免多线程下数据不一致的问题.

源码说明

public class AtomicInteger extends Number implements java.io.Serializable {
    // ...
    private static final Unsafe unsafe = Unsafe.getUnsafe();
    private static final long valueOffset;
	// 获取value的内存地址,即valueOffset
    static {
        try {
            valueOffset = unsafe.objectFieldOffset
                (AtomicInteger.class.getDeclaredField("value"));
        } catch (Exception ex) { throw new Error(ex); }
    }
	// volatile修饰value
    private volatile int value;

 public final int getAndSet(int newValue) {
 	// this 原子类实例,
	// value 属性的内存偏移地址,
	// newValue 待更新的值
 	return unsafe.getAndSetInt(this, valueOffset, newValue);
}

public final int getAndSetInt(Object var1, long var2, int var4) {
    int var5;
    do {
    	// 获取实例的value属性值
        var5 = this.getIntVolatile(var1, var2);
        // v1,v2始终可以获取最新的value属性值v_new,并传入当前value值v5用于对比,
        // v_new==v5,则将v4设为最新值,并返回true,跳出循环,否则重复
    } while(!this.compareAndSwapInt(var1, var2, var5, var4));

    return var5;
}
// compareAndSwapInt为native本地方法
// CPU层面调用CPU指令cmpxchg实现
public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5);

小结

CAS可以理解成是一种思想或算法,即比较与交换.而JUC包下的原子类通过结合使用volatile ,unsafe类以及CAS(通过do while循环不断比较,与自旋锁的实现类似)来解决多线程下数据安全问题.

  • 10
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值