浅谈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值的线程的值会被后面写入的覆盖掉吗?

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

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

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

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

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 第七章《索引》

    第七章《索引》

    2021年5月28日
    99
  • 什么叫文件中转站_文件怎么到文件中转站

    什么叫文件中转站_文件怎么到文件中转站以上

    2022年9月6日
    2
  • Apache tez_apache ii

    Apache tez_apache ii转发自这位大佬博客:https://www.cnblogs.com/rongfengliang/p/6991020.html你可能听说过ApacheTez,它是一个针对Hadoop数据处理应用程序的新分布式执行框架。但是它到底是什么呢?它的工作原理是什么?哪些人应该使用它,为什么?如果你有这些疑问,那么可以看一下BikasSaha和ArunMurthy提供的呈现“ApacheTez:加…

    2022年10月24日
    0
  • fillna函数用法_fill…with

    fillna函数用法_fill…withinplace参数的取值:True、FalseTrue:直接修改原对象False:创建一个副本,修改副本,原对象不变(缺省默认)method参数的取值:{‘pad’,‘ffill’,‘backfill’,‘bfill’,None},defaultNonepad/ffill:用前一个非缺失值去填充该缺失值backfill/bfill:用下一个非缺失值填充该缺失…

    2022年8月12日
    6
  • 7个最优秀的手机游戏引擎

    7个最优秀的手机游戏引擎随着智能手机成为主要的游戏平台,移动游戏引擎变得越来越流行。下面将介绍7个最优秀的手机游戏引擎。1.CoronaSDK游戏开发引擎这是一款实用Lua语言作为开发语言的游戏引擎,对我来说比起的其他的游戏引擎要好学一点。而且,Lua语言现在很有游戏开发都有相关的支持。Coronasdk官方网址:https://coronalabs.com/Lua学习网址,最好从菜鸟教程开始http://www.runoob.com/lua/lua-tutorial.htmlCoronaSDK开发欢迎W

    2022年6月6日
    55
  • PageHelper中的RowBounds「建议收藏」

    PageHelper中的RowBounds「建议收藏」RowBounds是处理ResultSet结果集进行分页,也就是说是逻辑分页,并不是物理分页。PageHelper是物理分页。

    2022年9月14日
    0

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

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