关于CAS的理解

CAS:compare and swap 比较交换。
简单原理:CAS包含3个数,内存位置,预期原值,新值。如果内存位置的值为预期原值,那么就将新值改变到内存位置中,否则不进行处理。这个过程是原子性的

但是,预期原值是哪来的呢?

详细原理(过程):
一个线程(进程)要对内存数据进行更改,首先要拿到这个原始数据A,然后经过自己的一系列操作变为B,变为B不是结果,结果是要将B写回内存中,此时就要用到CAS了,首先看内存中的值是否为还是A,如果是,说明还没有被其他线程(进程)更改过,自己在这期间就是对正确的内存做的正确的修改,所以可以直接将内存中的A改为B。但如果内存中的值已经不是A,说明有别的线程更改过,我们所操作的数也不是正确的,所以要进行重新来一次CAS。
明白了上述的原理之后,我们来一个例子:
一个进程有10个线程,和一个内存资源i,i = 0
多个线程中每个线程并发的对 公共的 i 进行i+1操作
这次我们不用lock,比如java中(synchronized),我们利用CAS来进行操作,理解理解是否起到了和锁一样的功能。

性能
CAS相比锁性能真的有那么好吗???
我们可以来分析一下:
1.CAS的过程是每个线程如果发现别人已经更改了数据,那么自己就会重复执行一遍CAS流程,相当于上次的操作白白耗费了CPU的资源。
2.锁的过程浪费在了哪里呢?获得锁,检测锁,释放锁等等。
通过上面的比较,不难总结出:

  • CAS 适合简单对象的操作,比如布尔值、整型值等

  • CAS 适合冲突较少的情况,如果太多线程在同时自旋,那么长时间循环会导致 CPU 开销很大

产生问题
ABA:进程有资源A,两个线程 t1,t2

  • t1负责修改A为B
  • t2负责修改B为A
  • 但是修改过的内存值不能在修改

t1首先要修改A为B,t2修改B为A。但是此时t1又看到有A出现,又马上修改为B,然后t2又开始操作。
解决办法:加个版本号(结构体里面配置内存值和修改位,或者版本号,根据自己的需求来判断)修改过后 则置修改位为1;当修改位为1,则不需要对该结构体进行更改。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值