当前位置:网站首页>比较并交换 (CAS) 原理
比较并交换 (CAS) 原理
2022-07-31 09:03:00 【clear0217】
比较并交换 (CAS) 原理
synchronized相当于是悲观锁,CAS相当于是乐观锁。
悲观锁:我现在要操作一个共享数据,我很悲观,我认为我操作的过程中,一定会被人给修改,会导致数据错误;我在操作这个数据之前,先给这个数据加了一把锁,synchronized,在我操作这个数据的期间,就只能是我来操作,其他任何人都操作不了。
**乐观锁:**我感觉在我操作这个数据的过程中,应该不会被人给修改。我先修改吗,然后修改完之后要设置这个变量的最新的值,此时我会对比一下,当前的这个值,是不是跟我在操作前看到的这个值是一样的,如果是一样的,那么说明可能就没有被人给修改过,如果没有被人修改过,那么我就可以来设置最新的值。
CAS,Compare and Swap,就是比较和交换。java并发包借助CAS实现了乐观锁的思想,synchronized是悲观锁思想。
CAS 操作包含三个操作数 —— 内存位置(V)、预期原值(A)和新值(B)。如果内存位置的值与预期原值相匹配,那么处理器会自动将该位置值更新为新值。否则,处理器不做任何操作。无论哪种情况,它都会在 CAS 指令之前返回该位置的值。(在 CAS 的一些特殊情况下将仅返回 CAS 是否成功,而不提取当前值。)CAS 有效地说明了“我认为位置 V 应该包含值 A;如果包含该值,则将 B 放到这个位置;否则,不要更改该位置,只告诉我这个位置现在的值即可。”
通常将 CAS 用于同步的方式是从地址 V 读取值 A,执行多步计算来获得新值 B,然后使用 CAS 将 V 的值从 A 改为 B。如果 V 处的值尚未同时更改,则 CAS 操作成功。
类似于 CAS 的指令允许算法执行读-修改-写操作,而无需害怕其他线程同时修改变量,因为如果其他线程修改变量,那么 CAS 会检测它(并失败),算法可以对该操作重新计算。清单 3 说明了 CAS 操作的行为(而不是性能特征),但是 CAS 的价值是它可以在硬件中实现,并且是极轻量级的(在大多数处理器中):
举个例子吧,比如int a = 3,这是内存中的当前值,然后你CAS(3, 5),第一个是旧的预期值,如果3和a是一样的,那么就将a修改为5。
CAS的缺点
1.cpu开销大
自旋锁的目的是为了占着CPU的资源不释放,等到获取到锁立即进行处理。在高并发的情况下,如果多个线程同时更新一个值不成功,就会一直自旋,增大cpu压力。
2.不能保证代码块的原子性
cas保证的是一个变量的原子性操作,如果要保证多个变量或者代码块的原子性,就要使用synchronized。
3.ABA问题(加版本号)
对于某一个数据,有一个线程将它操作后又恢复原状,而我们无法分辨。
ABA问题
在多线程场景下CAS会出现ABA问题,关于ABA问题这里简单科普下,例如有2个线程同时对同一个值(初始值为A)进行CAS操作,这三个线程如下
线程1,期望值为A,欲更新的值为B
线程2,期望值为A,欲更新的值为B
线程1抢先获得CPU时间片,而线程2因为其他原因阻塞了,线程1取值与期望的A值比较,发现相等然后将值更新为B,然后这个时候出现了线程3,期望值为B,欲更新的值为A,线程3取值与期望的值B比较,发现相等则将值更新为A,此时线程2从阻塞中恢复,并且获得了CPU时间片,这时候线程2取值与期望的值A比较,发现相等则将值更新为B,虽然线程2也完成了操作,但是线程2并不知道值已经经过了A->B->A的变化过程。
解决方法:
在变量前面加上版本号,每次变量更新的时候变量的版本号都+1,即A->B->A就变成了1A->2B->3A。
边栏推荐
猜你喜欢
![[Cloud native and 5G] Microservices support 5G core network](/img/c9/4ccacd1e70285c2ceb50c324e5018c.png)
[Cloud native and 5G] Microservices support 5G core network
![[MySQL exercises] Chapter 3 Common data types in MySQL](/img/11/66b4908ed8f253d599942f35bde96a.png)
[MySQL exercises] Chapter 3 Common data types in MySQL

云服务器部署 Web 项目
![[转载] Virtual Studio 让系统找到需要的头文件和库](/img/85/909c2ef52bbecb3faf7ed683fee65b.png)
[转载] Virtual Studio 让系统找到需要的头文件和库

关于挂载EXfat文件格式U盘失败的问题

ARC在编译和运行做了什么?

科目三:左转弯
![[Mini Program Project Development--Jingdong Mall] Custom Search Component of uni-app (Part 1)--Component UI](/img/73/a22ab1dbb46e743ffd5f78b40e66a2.png)
[Mini Program Project Development--Jingdong Mall] Custom Search Component of uni-app (Part 1)--Component UI

torch分布式训练

【小程序项目开发-- 京东商城】uni-app之自定义搜索组件(中)-- 搜索建议
随机推荐
Browser usage ratio js radar chart
skynet中一条消息从取出到处理完整流程(源码刨析)
SSM integration case study (detailed)
如何使用mysql binlog 恢复数据
【节选】吴恩达给出的AI职业生涯规划
如何在一台机器上(windows)安装两个MYSQL数据库
Flink1.15源码阅读flink-clients——flink命令行帮助命令
【小程序项目开发--京东商城】uni-app之自定义搜索组件(上)-- 组件UI
ecshop安装的时候提示不支持JPEG格式
奉劝那些刚参加工作的学弟学妹们:要想进大厂,这些核心技能是你必须要掌握的!完整学习路线!
【Redis高手修炼之路】Jedis——Jedis的基本使用
JSP pagecontext对象的简介说明
Job hunting product manager [9] How to write a good resume in job hunting season?
ARC在编译和运行做了什么?
来n遍剑指--09. 用两个栈实现队列
spark filter
浏览器使用占比js雷达图
Flink1.15源码阅读——PER_JOB vs APPLICATION执行流程
Flutter Paystack implements all options
35-Jenkins-Shared library application