当前位置:网站首页>比较并交换 (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
。
边栏推荐
- MySQL 视图(详解)
- Pytorch学习记录(七):自定义模型 & Auto-Encoders
- A, MySQL principle of master-slave replication
- 基于学生成绩管理系统(附源代码及数据库)
- 服务器上解压文件时提示“gzip: stdin: not in gzip format,tar: Child returned status 1,tar: Error is not recovera“
- 二叉树的搜索与回溯问题(leetcode)
- 状态机动态规划之股票问题总结
- MySQL 排序
- Flink1.15源码阅读——PER_JOB vs APPLICATION执行流程
- 5.for in 和 for of区别和使用
猜你喜欢
刷题《剑指Offer》day05
【RISC-V】risc-v架构学习笔记(架构初学)
来n遍剑指--07. 重建二叉树
服务器上解压文件时提示“gzip: stdin: not in gzip format,tar: Child returned status 1,tar: Error is not recovera“
SQL连接表(内连接、左连接、右连接、交叉连接、全外连接)
优信年营收16亿:亏损3亿 已与蔚来资本及58集团签署股权协议
【Unity】编辑器扩展-04-拓展Scene视图
【机器学习】用特征量重要度(feature importance)解释模型靠谱么?怎么才能算出更靠谱的重要度?
生成随机数
来n遍剑指--06. 从尾到头打印链表
随机推荐
JSP page对象简介说明
Small application project development, jingdong mall 】 【 uni - app custom search component (below) - search history
服务器上解压文件时提示“gzip: stdin: not in gzip format,tar: Child returned status 1,tar: Error is not recovera“
怎样修改MySQL数据库的密码
The torch distributed training
Hematemesis summarizes thirteen experiences to help you create more suitable MySQL indexes
mysql 数据去重的三种方式[实战]
C# 正则表达式汇总
matlab常用符号用法总结
JSP pagecontext对象的简介说明
编译器R8问题Multidex
postgresql generate random date, random time
[Yellow ah code] Introduction to MySQL - 3. I use select, the boss directly drives me to take the train home, and I still buy a station ticket
Scala基础【seq、set、map、元组、WordCount、队列、并行】
[MySQL exercises] Chapter 5 · SQL single table query
torch分布式训练
科目三:左转弯
MySQL 数据库基础知识(系统化一篇入门)
SSM整合案例分析(详解)
35-Jenkins-共享库应用