CAS及CAS自旋

article/2025/8/20 15:40:24

1. CAS简介

比较并交换(compare and swap, CAS),是原子操作的一种。在多线程没有锁的状态下,可以保证多个线程对同一个值的更新。

CAS可用于在多线程编程中实现不被打断的数据交换操作,从而避免多线程同时改写某一数据时由于执行顺序不确定性以及中断的不可预知性,产生的数据不一致问题。该操作通过将内存中的值与指定数据进行比较,当数值一样时将内存中的数据替换为新的值。

2. CAS的特点

1、CAS结合volatile可以实现无锁并发,适用于线程数少,多核CPU场景下。

线程数不要超过CPU核数

2、CAS是基于乐观锁实现(本身并无锁🔒,区别于synchronized)

3、CAS体现的是无锁并发、无阻塞并发

  • CAS的原子性 + volatile的可见性,不断的的【比较于交换】保证线程安全
  • 没有用锁🔒来保证线程安全,所以不会阻塞
  • 如果竞争激烈,会导致重试频繁发生,效率下降

3. 自旋–比较和交换

自旋: 就是不停的判断比较,看能否将值交换

我们都知道,多个线程在访问共享资源的时候,会产生同步问题,所以需要加锁来保证安全。但是,一旦加了锁,同一时刻只能有一个线程获取锁对象,效率自然变低了。

那在多线程场景下,不加锁的情况下来修改值,CAS是怎么自旋的呢?

在这里插入图片描述

【用图举例来说明】

  • 现在Data中存放的是num=0,线程A将num=0拷贝到自己的工作内存中计算(做+1操作)E=0,计算的结果为V=1
  • 由于是在多线程不加锁的场景下操作,所以可能此时num会被别的线程修改为其他值。此时需要再次读取num看其是否被修改,记再次读取的值为N
  • 如果被修改,即E !=N,说明被其他线程修改过。那么此时工作内存中的E已经和主存中的num不一致了,根据EMSI协议,保证安全需要重新读取num的值。直到E= N才能修改
  • 如果没被修改,即E =N,说明没被其他线程修改过。那门将工作内存中的E=0改为E=1,同时写回主存。将num=0改为num=1
    为了直观的说明,再来一个经典的转账例子:

要在当前状态的余额下减10

在这里插入图片描述

这就是自旋的比较和交换:

在多线程没有锁的状态下,可以保证多个线程访问对某一个值的更新。

4. 什么是ABA问题

举个不恰当的例子🙃。张三和他的女朋友李四分手了,经历了全球变暖以及黄金的贬值的重重考验和磨难后最终又复合。那么,在分手期间,张三是不知道李四有没有重新找过男朋友的。但是,最终的男盆友是自己就行了!这就是ABA问题。

回归到问题本身:

在线程A计算V的时候,可能线程B将num=0改为了num=2,线程C又将num=2改回了num=0(也有可能是线程B或这任意线程)。此时num的值虽然还时0,但是num已经不是一开始的num了。

用一句哲学的话来讲,就是:“世界上没有两片相同的树叶”!

5. ABA问题怎么解决

CAS是无法解决ABA问题的。解决的策略有哪些呢?

  1. 添加版本号

大家在更新手机APP的时候,每次更新时软件都会有版本号。你更新完软件,还是原来的应用,但是版本号就不一样了。

同样,ABA问题也可以这样来求解。

我们把值num加一个版本号tag,当有线程修改的时候,版本号就会发生变化。在读取E的时候,同时将版本号tag也读取上,在比较E=?=N的时候,同时比较tag是否发生了改变。

  1. 添加时间戳

添加世时间戳也可以解决。查询的时候把时间戳一起查出来,对的上才修改并且更新值的时候一起修改更新时间,这样也能保证,方法很多但是跟版本号都是异曲同工之妙。

6. 悲观锁

总是假设最坏的情况,每次取数据时都认为其他线程会修改,所以都会加锁(读锁、写锁、行锁等),当其他线程想要访问数据时,都需要阻塞挂起。在Java中,synchronized的思想就是悲观锁。

7. 乐观锁

总是认为不会产生并发问题,每次去取数据的时候总认为不会有其他线程对数据进行修改,因此不会上锁。

乐观锁总是认为不会产生并发问题,每次去取数据的时候总认为不会有其他线程对数据进行修改,因此不会上锁。

但是在更新时会判断其他线程在这之前有没有对数据进行修改,一般会使用版本号机制或CAS操作实现。java.util.concurrent包中借助CAS实现了区别于synchronized同步锁的一种乐观锁。

8. CAS锁升级

针对 synchronized 获取锁的方式,JVM 使用了锁升级的优化方式:

  • 先使用偏向锁优先同一线程,然后再次获取锁
  • 如果失败,就升级为 CAS 轻量级锁
  • 如果失败就会短暂自旋,防止线程被系统挂起
  • 最后如果以上都失败就升级为重量级锁
  • 锁是一步步升级上去的,最初是通过很多轻量级的方式锁定的。

9. CAS的三大问题

1、ABA问题

因为CAS需要在操作值的时候,检查值有没有发生变化,比如没有发生变化则更新,但是如果一个值原来是A,变成了B,又变成了A,那么使用CAS进行检查时则会发现它的值没有发生变化,但是实际上却变化了。

解决思路:
ABA问题的解决思路就是使用版本号。在变量前面追加上版本号,每次变量更新的时候把版本号加1,那么A->B->A就会变成1A->2B->3A。

从Java 1.5开始,JDK的Atomic包里提供了一个类AtomicStampedReference来解决ABA问题。这个类的compareAndSet方法的作用是首先检查当前引用是否等于预期引用,并且检查当前标志是否等于预期标志,如果全部相等,则以原子方式将该引用和该标志的值设置为给定的更新值。

2、循环时间长开销大

自旋CAS如果长时间不成功,会给CPU带来非常大的执行开销。
如果JVM能支持处理器提供的pause指令,那么效率会有一定的提升。

pause指令有两个作用:

  • 第一,它可以延迟流水线执行命令(de-pipeline),使CPU不会消耗过多的执行资源,延迟的时间取决于具体实现的版本,在一些处理器上延迟时间是零
  • 第二,它可以避免在退出循环的时候因内存顺序冲突(Memory Order Violation)而引起CPU流水线被清空(CPU Pipeline Flush),从而提高CPU的执行效率。

3、只能保证一个共享变量的原子操作

当对一个共享变量执行操作时,我们可以使用循环CAS的方式来保证原子操作,但是对多个共享变量操作时,循环CAS就无法保证操作的原子性,这个时候就可以用锁。

还有一个取巧的办法,就是把多个共享变量合并成一个共享变量来操作。比如,有两个共享变量i = 2,j = a,合并一下ij = 2a,然后用CAS来操作ij。

从Java 1.5开始,JDK提供了AtomicReference类来保证引用对象之间的原子性,就可以把多个变量放在一个对象里来进行CAS操作。

原文地址:https://blog.csdn.net/weixin_43232955/article/details/107452893
https://www.jianshu.com/p/2db33f276ef8


http://chatgpt.dhexx.cn/article/JMNoWnPA.shtml

相关文章

自旋玻璃(spin glass)、自旋冰(spin ice)和量子自旋液体(quantum spin liquid)(之二)

文章目录 13. 几何阻挫(Geometrical frustration)13.1 磁序(Magnetic ordering)13.2 数学定义13.3 水冰(water ice)13.4 Paulings model 的扩展:广义的阻挫13.5 人工几何阻挫铁磁体13.6 没有晶格…

CAS自旋

文章目录 1. CAS简介2. CAS的特点3. 自旋–比较和交换4. 什么是ABA问题5. ABA问题怎么解决6. 悲观锁7. 乐观锁8. CAS锁升级 CAS面试提问环节: synchronized、ReentrantLock、CAS全家桶发售HashMap、Hashtable、ConcurrentHashMap组合拳出击 1. CAS简介 比较并交换(…

自旋玻璃(spin glass)、自旋冰(spin ice)和量子自旋液体(quantum spin liquid)(之一)

文章目录 1. Giorgio Parisi 简介2. 复杂无序系统2.1 相变、序参量与对称性破缺2.2 复杂系统 3. 自旋玻璃简介3.1 自旋冻结3.2 亚稳态3.3 磁化弛豫3.4 玻璃化和无序系统3.5 Ising model3.6 自旋玻璃模型3.7 自旋玻璃相变 4. 磁场中的现象5. Edwards-Anderson model6. Sherringt…

office卸载工具怎么用(官方干净卸载方法)

https://jingyan.baidu.com/article/39810a23593f37b636fda60d.html

Office卸载安装问题

卸载Office 问题描述 此前已安装过新的Office,按照正常的卸载流程卸载后(控制面板卸载后),安装新的Office时,提示: 无法安装64位版本的Office,因为在电脑上已有32位程序。如下图所示。 **解…

32位office卸载不干净怎么办如何删除32位Office

以前在电脑上安装了32位系统的Office,现在想要换成64位的Office,但是在安装的时候提示无法进行安装,需要先卸载以前的32位Office,出现这种情况怎么办呢?如何彻底卸载干净32位系统的Office呢?下面就一起来看…

Office卸载不干净,注册表项权限修改后仍然无法删除的问题

Office卸载不干净,注册表项权限修改后仍然无法删除的问题 针对卸载Office最极端的情况,试试以下方法。 1.卸载开始菜单的office; 可以借助以下工具进行进行清除,完全卸载(但是对本人无效) 链接:https://…

mac m1 office卸载重装(学校官方正版)

卸载office 1、应用程序中将所有的microsoft相关软件移到废纸篓,可能还有outlook或者onedrive,清空废纸篓 2、cmdshiftG,输入/Library/Preferences,删除所有com.Microsoft开头的文件 3、进入/Library/PrivilegedHelperTools&…

卸载32位office安装64位office卸载不完全导致不能安装64位office时解决办法

转载自https://blog.csdn.net/zzfenglin/article/details/60780831 问题描述 安装64位office办公软件的时候提示已经安装32位的office办公软件所以无法继续安装,但实际上之前安装的32位的office办公软件已经卸载了。问题现象截图如下: 解决办法 从问题描…

office2019 完美卸载

记录下我日常手贱的经历。 事情的起因呢,是在家办公的时候呢,突然要写一份文档,然后呢,我的wps过期了,只能看,而不能编辑。然后我就打算装个office2019感受下。结果我就卸载了原来安装过但是已经过期了的o…

Office uninstall(专业office卸载工具)绿色单文件版V1.8.3 全面清除office卸载残留

Office uninstall 是一款专门为微软Office办公软件量身定做的office卸载工具,可以帮助大家彻底卸载已经安装到电脑上的Office软件,彻底解决office卸载不干净,无法重新安装的问题,全面兼容office2003、office2007、office2010、off…

Win10预装Office卸载工具

联想软件远程服务,让您足不出户,轻松解决电脑问题!软件调试、电脑加速、游戏加速、重装系统、修复浏览器、安装驱动,远程or上门?联想专家一对一服务任您挑选! 重要提示:您需要在电脑端下载并运行…

将office办公软件彻底从计算机中卸载清除

此情况针对于计算机系统中可能包含两个版本或更多的office同时存在导致在新建各种文档时会有些冲突,卸载不干净后,重新安装回去也还是无济于事,所以经过探索,将成功的方法发布给大家,希望对大家有所帮助。 有两种用于彻…

关于机器学习SVM中KKT条件的深入理解推导

关于机器学习SVM中KKT条件的深入理解推导 目前为止的已知KKT条件违反KKT条件的情况参考文献 本文面向在寻找KKT条件相关推到文章的读者,且默认前面关于svm的松弛下的模型和smo算法推到都已经了解。如果没有或者需要温习,请参看支持向量机SVM与SMO算法的的…

理解KKT条件

一、引言 对于无约束最优化问题,其搜索空间是无界的,只要确定了搜索方向和步长因子,便可以在一轮或几轮迭代之后找到最优解或近似最有解。这里举个不太恰当的例子,无约束最优化如同在浩瀚的宇宙中寻找体积最大的星球,你…

KKT条件(卡罗需-库恩-塔克条件)

1,定义 KKT是啥? 它是Karush、Kuhn和Tucker三个人。这三个人单独提出了在非线性规划中获得最优解的必要条件。 看着很复杂呀? 还好啦。。。只是将拉格朗日乘数法中的等式约束条件泛化到了不等式。 2,先来几个简单例子 为什么要…

KKT条件(Karush–Kuhn–Tucker conditions)

在约束最优化问题中,常常利用有条件的拉格朗日乘子法,进而一步步推导KKT条件。 1.最优化条件和下降搜索 给定一个多变量可微函数 ,是的局部最小值,这时有 如果,就存在使得 (对这边做个解释:…

机器学习理论基础:线代相关、PCA、KKT条件、贝叶斯统计

机器学习理论基础:线代相关、PCA、KKT条件、贝叶斯统计 摘要1.线性代数相关与证明1.1.线性相关和生成子空间1.1.1.线性方程组的矩阵表示1.1.2.生成子空间1.1.3.线性相关1.1.4.方程组通过逆矩阵求解时的考量 1.2.证明:通过迹运算描述矩阵的Frobenius范数1…

KKT条件(Karush-Kuhn-Tucker Conditions)

总目录 一、 凸优化基础(Convex Optimization basics) 凸优化基础(Convex Optimization basics) 二、 一阶梯度方法(First-order methods) 梯度下降(Gradient Descent)次梯度&am…

windows下Armadillo+openBlas

1、处理Armadillo 1.1、http://arma.sourceforge.net/download.html#windows下载Armadillo,解压后把其中的include文件夹完整拷贝出来,放到某处,我放在了D:\Armadillo里 1.2、修改D:\Armadillo\include\armadillo_bits\config.hpp&#xff…