CAS(自旋)原理解析,及ABA问题

概念:
CAS(比较并且交换)是无锁优化,或者叫自旋,还有自适应自旋,我们通过Atomic类(原子的)。常常配合循环使用,由于这些操作,老是来回的加锁,减锁,加锁情况特别多,我们java提供了这样常见操作的一个类,这些类的内部就自动带了锁,这些锁不是synchronized重量级锁,而是CAS操作来实现(无锁)。

凡是以Atomic开头的类都是用CAS来保证线程安全的。AtomicInteger里面包装了

int类型,这个int类型的count++操作是线程安全的,还有拿值等等是线程安全

的。工作开发中经常会有一个值所有的线程共同访问他往上递增。如何使用AtomicI

nteger,如下图代码,AtomicInteger用法:

在这里插入图片描述
那么cas的内部实现的原理是什么呢?AtomicInteger类的incrementAndGet()调用了Unsafe类的getAndAdddInt()方法,下图是源码的实现:
在这里插入图片描述
在这里插入图片描述
当然了,这也属于一个CompareAndSetInt()操作,比较并且设定。

我原来想改变某一个值0,我想把它变成1,但是我想线程安全,就必须加synchroni

zed,现在我可以用另外一种操作代替这把锁,那就是cas操作,把它想象成一个方法

cas(V,expected,NewValue)。

V:要修改的值。

expected:期望值。期望会是几。

NewValue:要设定的新值。

比方说:当前的这个线程想改这个值,我期望你是0,你就不能是1;如果是1,那就

说明我这个值不对,然后想把你变成1。大概就是:原来这个值是变为3了,我这个线

程想修改这个值的时候我一定期望你现在是3,是3我才改,如果在我修改的过程你变

4了,说明就有另外一个线程修改过该值,那我cas就再重新试一下,再试的时候,

我希望你的这个值是4,在修改的时候期望值是4,没有其它线程修改该值,那好我

给你改成5,这样就是cas操作。

当你判断的时候,发现是我的期望值,还没有进行新值设定的时候值发生了改变怎么办,cas是cpu的原语支持,也就是说cas是cpu指令级别上的支持
中间不能被打断。这就是cas的一些知识,望对大家有点帮助。

二:cas的一个ABA问题:

假如说你有一个值,我拿到这个值是0,想把它变成2,我拿到1用cas操作,期望值是

1,准备变成2,对象是Object,在这个过程中没有一个线程改过我这个值,肯定可

修改。如果有一个线程在这个过程中把这个1修改成了2后来又变回1,中间值更改过

但是不影响我后面的操作,这就是ABA问题。

如何解决这个问题呢?

如果是int类型的,最终值是你期望的。没有关系。确实想要解决的话,就是加版本,做任何一个值的修改,修改完加一,后面检查的时候连同版本号一起检查。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值