CAS总结

CAS:compare and Swap 翻译成比较并交换

偏移量: 指的是该元素在二进制文件中的位置

CAS有3个操作数,内存值V,旧的预期值A,要修改的新值B。当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做。

compareAndSet这个方法主要调用unsafe.compareAndSwapInt这个方法,这个方法有四个参数,其中第一个参数为需要改变的对象,
第二个为偏移量(即之前求出来的valueOffset的值),第三个参数为期待的值,第四个为更新后的值。整个方法的作用即为若调用该方法时,
偏移量的值与expect这个值相等,那么则将value修改为update这个值,并返回一个true,如果调用该方法时,value的值与expect这个值不相等,那么不做任何操作,并范围一个false。

CAS 操作中包含三个操作数 —— 需要读写的内存位置(V)、进行比较的预期原值(A)和拟写入的新值(B)。如果内存位置V的值与预期原值A相匹配,那么处理器会自动将该位置值更新为新值B。否则处理器不做任何操作。
无论哪种情况,它都会在 CAS 指令之前返回该位置的值。(在 CAS 的一些特殊情况下将仅返回 CAS 是否成功,而不提取当前值。)CAS 有效地说明了“ 我认为位置 V 应该包含值 
A;如果包含该值,则将 B 放到这个位置;否则,不要更改该位置,只告诉我这个位置现在的值即可。 ”这其实和乐观锁的冲突检查+数据更新的原理是一样的。

 

AtomicInteger没有锁的情况下是如何保证数据的准确性

Private volatile int value  // 保持内存可见性和防止指令重排序

没有锁的情况下需要借助volatile语,来保证线程间的数据是可见的这样在获取变量值的时候才能直接读取

Final 方法不可被重写,final类不可被继承

Public final int get(){

Return value;

}

那么我们来看看value的i++是怎么实现的

Public final int incrementAndGet(){

for (;;) {

        int current = get();

        int next = current + 1;

        if (compareAndSet(current, next))

            return next;

}

}

 

这里采用了CAS操作,每次从内存中读取数据然后将此数据+1后的结果进行CAS。如果成功就返回结果,否则重试直到成功为止。

其中unsafe.compareAndSwapInt(this, valueOffset, expect, update);

类似:

if (this == expect) {

 this = update

 return true;

} else {

return false;

}

那么问题就来了,成功过程中需要2个步骤:比较this == expect,替换this = update,compareAndSwapInt如何这两个步骤的原子性呢? 参考CAS的原理。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值