CAS机制详解以及ABA问题的危害和解决方案

首先,先讲一下 CAS机制到底怎么运作。让我们一探究竟。

1.什么是CAS机制

CAS是英文单词Compare And Swap的缩写,翻译过来就是比较并替换。

CAS机制当中使用了3个基本操作数:内存地址V,旧的预期值A,要修改的新值B。

更新一个变量的时候,只有当变量的预期值A和内存地址V当中的实际值相同时,才会将内存地址V对应的值修改为B。

这样说或许有些抽象,我们来看一个例子:

1.在内存地址V当中,存储着值为10的变量。

2.此时线程1想要把变量的值增加1。对线程1来说,旧的预期值A=10,要修改的新值B=11。

3.在线程1要提交更新之前,另一个线程2抢先一步,把内存地址V中的变量值率先更新成了11。

4.线程1开始提交更新,首先进行A和地址V的实际值比较(Compare),发现A不等于V的实际值,提交失败。

5.线程1重新获取内存地址V的当前值,并重新计算想要修改的新值。此时对线程1来说,A=11,B=12。这个重新尝试的过程被称为自旋

6.这一次比较幸运,没有其他线程改变地址V的值。线程1进行Compare,发现A和地址V的实际值是相等的。

7.线程1进行SWAP,把地址V的值替换为B,也就是12。

2.适用场景,以及Java中哪些地方用到了CAS机制
  1. concurrent.Atomic 包下一系列Atomic开头的包装类,利用了CAS机制。例如AtomicBooleanAtomicIntegerAtomicLong。它们分别用于Boolean,Integer,Long类型的原子性操作。
  2. Lock系列类的底层实现
  3. Java1.6以上版本,synchronized转变为重量级锁之前,也会使用CAS机制。
众所周知锁有两种:乐观锁与悲观锁。

​ 独占锁是一种悲观锁,而 synchronized 就是一种独占锁,synchronized 会导致其它所有未持有锁的线程阻塞,而等待持有锁的线程释放锁。

​ 所谓乐观锁就是,每次不加锁而是假设没有冲突而去完成某项操作,如果因为冲突失败就重试,直到成功为止。而乐观锁用到的机制就是CAS。

从思想上来说,Synchronized属于悲观锁,悲观地认为程序中的并发情况严重,所以严防死守。CAS属于乐观锁,乐观地认为程序中的并发情况不那么严重,所以让线程不断去尝试更新。

讲一下synchronized的性能问题

Synchronized关键字会让没有得到锁资源的线程进入BLOCKED状态,而后在争夺到锁资源后恢复为RUNNABLE状态,这个过程中涉及到操作系统用户模式内核模式的转换,代价比较高。

尽管Java1.6为Synchronized做了优化,增加了从偏向锁轻量级锁再到重量级锁的过度,但是在最终转变为重量级锁之后,性能仍然较低。

jdk1.6以后 对synchronized锁做了哪些优化

1.适应自旋锁

自旋锁:为了减少线程状态改变带来的消耗 不停地执行当前线程

2.锁消除:

不可能存在共享数据竞争的锁进行消除

3.锁粗化:

将连续的加锁 精简到只加一次锁

4.轻量级锁:

无竞争条件下 通过CAS消除同步互斥

5.偏向锁:

无竞争条件下 消除整个同步互斥,连CAS都不操作。

那么这么看来CAS看起来不错,那是否可以以后不用synchronized,都用CAS呢。

实际上是不可以的,这两种机制没有绝对的好与坏,关键看使用场景**。在并发量非常高的情况下,反而使用synchronized 同步锁比较合适**

3.CAS的优缺点

优点:

在并发量不是很高时cas机制会提高效率。

缺点:

1.CPU开销较大

在并发量比较高的情况下,如果许多线程反复尝试更新某一个变量,却又一直更新不成功,循环往复,会给CPU带来很大的压力。

2.不能保证代码块的原子性

CAS机制所保证的只是一个变量的原子性操作,而不能保证整个代码块的原子性。比如需要保证3个变量共同进行原子性的更新,就不得不使用Synchronized了。

因为它本身就只是一个锁住总线的原子交换操作啊。两个CAS操作之间并不能保证没有重入现象。

3.ABA问题

这是CAS机制最大的问题所在。

4.进一步探讨ABA问题

大家想一下,上边我们提到CAS存在 ABA问题,但是大家有没有想过,表面上看ABA问题并不对我们有啥影响啊,比如 线程1 要把 int 变量a 从 1修改为 2, 在a 读完 a的 旧值1之后 ,即将去替换 内存中的值的时候,线程2 也读取了a 的旧值 并将其修改为 2,然后又修改成了 1, 此事 a的值还是1 ,和 a 读到的旧值 1 一样,这看起来是没啥问题的,对我们的业务没啥影响。这是一种特殊情况。

但是大家想一下 到底 哪种情况下 ABA问题 会对我们的业务产生影响呢?

上诉描述特殊情况 可能适用于库存的操作。表面上对业务不会产生影响。

但是对于下面的场景可能就是严重的事故了。

例如:

小牛取款,由于机器不太好使,多点了几次取款操作。后台threadA和threadB工作,
此时threadA操作成功(100->50),threadB阻塞。正好牛妈打款50元给小牛(50->100),
threadC执行成功,之后threadB运行了,又改为(100->50)。
牛气冲天,lz钱哪去了???

然后怎么去解决优化呢?

对内存中的值加个版本号,在比较的时候除了比较值还的比较版本号。

java:AtomicStampedReference就是用版本号实现cas机制。

参考文档:https://blog.csdn.net/qq_32060101/article/details/103558002

CAS机制详解以及ABA问题的危害和解决方案相关推荐

  1. java cas机制_Java CAS机制详解

    CAS目的: 在多线程中为了保持数据的准确性,避免多个线程同时操作某个变量,很多情况下利用关键字synchronized实现同步锁,使用synchronized关键字修可以使操作的线程排队等待运行,可 ...

  2. PHP autoload机制详解

    PHP autoload机制详解 转载自 jeakccc PHP autoload机制详解 (1) autoload机制概述 在使用PHP的OO模式开发系统时,通常大家习惯上将每个类的实现都存放在一个 ...

  3. 模糊匹配 读音_onenote搜索机制详解②:两种搜索模式,模糊与精确匹配

    先从纯文本搜索讲起,这是最基本也是最重要的. 从这篇开始,以及接下来连续几篇文章,都会介绍搜索的基础功能.注意,这几篇文章中谈论的都是基本的.正常的搜索功能,暂时不考虑Bug等因素. 在很多软件(例如 ...

  4. Java类加载机制详解【java面试题】

    Java类加载机制详解[java面试题] (1)问题分析: Class文件由类装载器装载后,在JVM中将形成一份描述Class结构的元信息对象,通过该元信息对象可以获知Class的结构信息:如构造函数 ...

  5. Numpy的广播机制详解(broadcasting)

    Numpy的广播机制详解(broadcasting) 广播(Broadcast)是 numpy 对不同形状(shape)的数组进行数值计算的方式, 对数组的算术运算通常在相应的元素上进行. 如果两个数 ...

  6. Session机制详解及分布式中Session共享解决方案

    Session机制详解及分布式中Session共享解决方案 参考文章: (1)Session机制详解及分布式中Session共享解决方案 (2)https://www.cnblogs.com/jing ...

  7. java异常处理机制详解

    java异常处理机制详解 参考文章: (1)java异常处理机制详解 (2)https://www.cnblogs.com/vaejava/articles/6668809.html 备忘一下.

  8. SpringMVC异常处理机制详解[附带源码分析]

    SpringMVC异常处理机制详解[附带源码分析] 参考文章: (1)SpringMVC异常处理机制详解[附带源码分析] (2)https://www.cnblogs.com/fangjian0423 ...

  9. 动态代理机制详解(JDK 和CGLIB,Javassist,ASM)

    2019独角兽企业重金招聘Python工程师标准>>> 在运行时期可以按照Java虚拟机规范对class文件的组织规则生成对应的二进制字节码.当前有很多开源框架可以完成这些功能,如A ...

最新文章

  1. windows下mongodb的安装与配置
  2. (转)刘汝佳书上出现的一些题目
  3. AC日记——字符串位移包含问题 1.7 19
  4. c# winform中窗体切换后释放及防止重复生成
  5. 【结论】棋盘(jzoj 2297)
  6. linux监控任务跑满,Linux服务器带宽和CPU跑满或跑高排查
  7. linux句柄过大导致无法登陆
  8. href标签带上了localhont地址怎么删除_如何找回删除的微信好友?
  9. Can't connect to MySQL server on 'localhost' (10038)
  10. 计算机软考初级信息技术试题及答案,2015年软考信息技术处理员考试模拟试题及答案...
  11. python 日期的周数_术业有专攻:日期时间模块datetime
  12. PaysApi第三方支付接口的接入与使用 React前端SSM后端
  13. 计算机软件研究方法与技术路线,项目的研究方法与技术路线
  14. matlab运行时间特别长,Matlab运行时间过长
  15. 简单理解数据库游标cursor
  16. git memery 后 push到远程,如何回滚
  17. kali流量转发后依然断网_虚拟运营商流量卡列表
  18. php+Sphinx分词中间件的认识和基础使用(亲测)
  19. vb里的lbound和ubound的用法
  20. 2022元宇宙十大 “闪光时刻”

热门文章

  1. 患者监护系统可行性分析
  2. 在CSS布局中让Floats轻拂
  3. 我00后,会Python,月薪5000,兼职1.5w
  4. 红尘梦醒雪无踪,花落无息香如故
  5. 读围城论方鸿渐与孙柔嘉的爱情
  6. 基于Android的谷歌地图地理围栏功能开发
  7. 几种请求方式的使用get、post、put
  8. fatal error: opencv2\core\core.hpp: No such file or directory
  9. 逻辑回归预测瘀血阻络证||LogRegression 二分类 python3|五折交叉验证
  10. FSL安装教程(Ubuntu)