AtomicInteger CAS分析

AtomicInteger count = new AtomicInteger(0);

count.incrementAndGet();

public final int incrementAndGet() {
        return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
}

// var1 AtomicInteger对象
// var2 地址偏移量
// var3 增加量
public final int getAndAddInt(Object var1, long var2, int var4) {
        int var5;
        do {
            // 获取该var1对象的var2地址的值
            var5 = this.getIntVolatile(var1, var2);
            // 如果var2的值跟var5的值相等,则进行+1
            // 否则则进行重试
        } while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));

        return var5;
    }

模拟场景:A线程和B线程同时进行自增,假设初始值为1,两个线程进行自增,要求结果=3

1. A线程先拿到值 var5 = this.getIntVolatile(var1, var2) = 1,接着要进行自增时,让出了CPU即由B执行

2. 由于A还没自增就让出了CPU,所以B线程拿到的var5还是1,接着执行自增逻辑,比较var5的值和地址偏移量var2里的值是否一致,结果都等于1,所以将var5的值+1,B线程结束,让出CPU,此时值为2.

3. A线程重新拿到CPU,此时A线程里的var5还是1,进行自增时,偏移量var2的值已被B线程更改为2,所以进行比较时var5=1与var2=2的值不相等,自增失败返回false,此时再次进行重试,由于此时只有A线程在操作,就会像步骤2一样自增成功。

优点:通过这种轮训方式去自增,不会像加锁一样阻塞线程。

缺点:三个线程,A增,B增,C减。

A先拿到值,B先完成自增,接着C再完成自减,最后A再完成自增。

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值