CAS机制详解以及ABA问题的危害和解决方案
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机制
- concurrent.Atomic 包下一系列Atomic开头的包装类,利用了CAS机制。例如AtomicBoolean,AtomicInteger,AtomicLong。它们分别用于Boolean,Integer,Long类型的原子性操作。
- Lock系列类的底层实现
- 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问题的危害和解决方案相关推荐
- java cas机制_Java CAS机制详解
CAS目的: 在多线程中为了保持数据的准确性,避免多个线程同时操作某个变量,很多情况下利用关键字synchronized实现同步锁,使用synchronized关键字修可以使操作的线程排队等待运行,可 ...
- PHP autoload机制详解
PHP autoload机制详解 转载自 jeakccc PHP autoload机制详解 (1) autoload机制概述 在使用PHP的OO模式开发系统时,通常大家习惯上将每个类的实现都存放在一个 ...
- 模糊匹配 读音_onenote搜索机制详解②:两种搜索模式,模糊与精确匹配
先从纯文本搜索讲起,这是最基本也是最重要的. 从这篇开始,以及接下来连续几篇文章,都会介绍搜索的基础功能.注意,这几篇文章中谈论的都是基本的.正常的搜索功能,暂时不考虑Bug等因素. 在很多软件(例如 ...
- Java类加载机制详解【java面试题】
Java类加载机制详解[java面试题] (1)问题分析: Class文件由类装载器装载后,在JVM中将形成一份描述Class结构的元信息对象,通过该元信息对象可以获知Class的结构信息:如构造函数 ...
- Numpy的广播机制详解(broadcasting)
Numpy的广播机制详解(broadcasting) 广播(Broadcast)是 numpy 对不同形状(shape)的数组进行数值计算的方式, 对数组的算术运算通常在相应的元素上进行. 如果两个数 ...
- Session机制详解及分布式中Session共享解决方案
Session机制详解及分布式中Session共享解决方案 参考文章: (1)Session机制详解及分布式中Session共享解决方案 (2)https://www.cnblogs.com/jing ...
- java异常处理机制详解
java异常处理机制详解 参考文章: (1)java异常处理机制详解 (2)https://www.cnblogs.com/vaejava/articles/6668809.html 备忘一下.
- SpringMVC异常处理机制详解[附带源码分析]
SpringMVC异常处理机制详解[附带源码分析] 参考文章: (1)SpringMVC异常处理机制详解[附带源码分析] (2)https://www.cnblogs.com/fangjian0423 ...
- 动态代理机制详解(JDK 和CGLIB,Javassist,ASM)
2019独角兽企业重金招聘Python工程师标准>>> 在运行时期可以按照Java虚拟机规范对class文件的组织规则生成对应的二进制字节码.当前有很多开源框架可以完成这些功能,如A ...
最新文章
- windows下mongodb的安装与配置
- (转)刘汝佳书上出现的一些题目
- AC日记——字符串位移包含问题 1.7 19
- c# winform中窗体切换后释放及防止重复生成
- 【结论】棋盘(jzoj 2297)
- linux监控任务跑满,Linux服务器带宽和CPU跑满或跑高排查
- linux句柄过大导致无法登陆
- href标签带上了localhont地址怎么删除_如何找回删除的微信好友?
- Can't connect to MySQL server on 'localhost' (10038)
- 计算机软考初级信息技术试题及答案,2015年软考信息技术处理员考试模拟试题及答案...
- python 日期的周数_术业有专攻:日期时间模块datetime
- PaysApi第三方支付接口的接入与使用 React前端SSM后端
- 计算机软件研究方法与技术路线,项目的研究方法与技术路线
- matlab运行时间特别长,Matlab运行时间过长
- 简单理解数据库游标cursor
- git memery 后 push到远程,如何回滚
- kali流量转发后依然断网_虚拟运营商流量卡列表
- php+Sphinx分词中间件的认识和基础使用(亲测)
- vb里的lbound和ubound的用法
- 2022元宇宙十大 “闪光时刻”
热门文章
- 患者监护系统可行性分析
- 在CSS布局中让Floats轻拂
- 我00后,会Python,月薪5000,兼职1.5w
- 红尘梦醒雪无踪,花落无息香如故
- 读围城论方鸿渐与孙柔嘉的爱情
- 基于Android的谷歌地图地理围栏功能开发
- 几种请求方式的使用get、post、put
- fatal error: opencv2\core\core.hpp: No such file or directory
- 逻辑回归预测瘀血阻络证||LogRegression 二分类 python3|五折交叉验证
- FSL安装教程(Ubuntu)