浅谈CAS原理_cas算法原理

浅谈CAS原理_cas算法原理1.背景我们知道,synchronized就是一种独占锁,独占锁是一个悲观锁,会导致其他所有需要锁的线程挂起,等待持有锁的线程释放锁。而另一种更加有效的锁就是乐观锁,CAS就是一种乐观锁2.CAS原理CAS(CompareAndSwap),比较并交换。我们知道,如果我要对一个变量进行操作,可以分为三个步骤读取该变量的值进行一系列的运算得到新的结果将运算的结果保存这儿需要知道CAS中有三个概念:内存地址的值V,旧值(从内存地址读取到的值)A,新值(进行操作后的结果值)。对应上面三

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

1. 背景

我们知道,synchronized就是一种独占锁,独占锁是一个悲观锁,会导致其他所有需要锁的线程挂起,等待持有锁的线程释放锁。而另一种更加有效的锁就是乐观锁,CAS就是一种乐观锁

2. CAS原理

CAS(Compare And Swap),比较并交换。我们知道,如果我要对一个变量进行操作,可以分为三个步骤

  1. 读取该变量的值
  2. 进行一系列的运算得到新的结果
  3. 将运算的结果保存

这儿需要知道CAS中有三个概念:内存地址的值V,旧值(从内存地址读取到的值)A,新值(进行操作后的结果值)B。对应上面三个步骤就是:值V保存在内存中,要修改的时候,会先去读取该内存中的值,读取到的值为A,此时A=V,然后进行操作得到结果B,此时需要将B写入内存才算是对该变量进行了完整的修改。那么此时需要再去读取内存中的值,判断该值是否等于A,如果等于,那么就直接将B写入。如果不等于,说明你在运算的过程中,其他的线程对该变量已经做了修改,那么你此时得到的这个B是没有意义的。不能写入。只能再次重复上面的操作(自旋),重新读取内存中的值,计算之后再进行比较,直到B可以被保存为止。这就是CAS的原理。

3. ABA问题

但是这种方式会有一个问题:ABA,就是说你在要保存B的时候,会去读取内存中的值判断是否和A相等,确保这期间没有其他线程操作过该变量。但是如果相等的话,你能确认这期间这个值没有被修改过吗?有可能期间被多次修改了,只不过最后得到的值恰好和原来的A相等。所以你不能保证相等时就是没有被修改过。这种情况可以加一个版本号来判断。例如1A-2B-3A,这样你就知道这个A其实已经不是原来的那个A了。

4. 缺点

因为该机制是没有加锁的,所有线程都可以任意操作该变量,虽然可以确保线程安全,但是如果并发太大,导致很多线程都在操作该变量,这会导致有大量的线程进行自旋,这无疑是增加了CPU的资源消耗。

5. 疑问

其实我自己有个疑问,这个真的安全吗?在保存B之前会判断内存中的值是否和A相等,相等就可以保存B。那如果有多个线程在操作该变量,操作完之后去读取内存中的值,并和各自线程中的A进行比较,假设这些线程都是在其他线程写入之前读取到内存中的值,也就是这几个线程读取到的值都和A相等,那么在写入的时候不就会出现先写入B值的线程的值会被后面写入的覆盖掉吗?

这个可能是自己对操作系统底层的原理不太了解,所以会有这样的疑问吧。

希望会这个问题的大佬不吝赐教,也希望自己以后在搞懂这个问题之后,来这儿将这个问题解决掉。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/184106.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号