多线程CAS八股文

是啥?

CAS 比较和交换(compare and swap),一个CAS有三个操作

  1. 比较内存和寄存器1的值是否相等
  2. 如果相对,就把寄存器2的值写入内存
  3. 返回操作是否成功

本质上是CPU的指令,设计到的操作不是原子性的,但是由于这个指令的原子性的,所以整体就是原子性的。

在这段代码中,可以把address理解为内存,expectValue是寄存器1,swapValue是寄存器2,首先会判断address的值是否和expectValue的值是否相等,如果是相等,就会把swapValue的值给写入到内存中去。

CAS本质是CPU的指令,操作系统对他进行了一些封装,提供一些api给c++使用,JVM又是基于C++实现的,所以JVM中也可以调用CAS的操作。

CAS的主要用途:实现原子类

在JAVA标准库中,在java.util.concurrent.atomic中

提供这些原子类,可以实现在不加锁的情况下解决线程安全问题同时又可以提高性能

在这段代码中,首先需要实例化一个CAS对象AtomicInteger对象,然后不需要进行加锁,创建两个线程让他们分别去进行自增5000,可以看出最后并没有出现线程安全问题且这个程序的正常退出,退出码为code0.

点开具体的实现就会发现,这个就是调用了JVM封装好了的CAS

为什么CAS能够保证线程安全?

Value内存的值,oldvalue寄存器的值

CAS会判断内存的值是否和寄存器一样,如果是的话就会进行修改,如果不是就会返回false然后就进入循环体进行重新读取

假设现在存在两个线程

第一个线程现在内存中读取到value为0,然后这个时候随机调度导致线程2开始执行,他因为寄存器和内存是一样的,所以就触发修改操作,把内存修改成1,同时把自己寄存器在内存中读取成1,因为第一个线程会去读取内存,发现不一样就不会修改,会去重新把内存中的值读取到寄存器再修改,这就保证了线程的安全

使用CAS实现自旋锁

在这段使用CAS模拟实现自旋锁的代码中,首先是创建了一个空线程,然后写一个lock和unlock方法。在lock中使用CAS反复的去读内存和寄存器,如果不一样就一直自旋等待,直到另外一个线程释放锁,如果一样就把Thread.currentThread赋值给this.owner。

CAS的ABA问题

ABA问题是啥?

举个例子:

我们知道CAS的工作模式是先判断内存和寄存器的值,一样才会进行修改,现在假设你的账户有1000块,某天你去ATM机取钱,这个时候你要取500,由于卡了一下,所以多按了几下,导致多了几个线程,他们都是会执行扣款500的操作,这个时候第一个线程成功了,你被扣了500块钱,现在你的账户只有500,恰巧在这个时候,老妈给你转了500块,这个时候你的账户又变成了1000块,由于CAS的工作模式是在内存和寄存器之间进行比较,这个时候发现还是1000块,又执行了扣款500,这个时候相当于我只取出了500,但是被扣款了1000,这个就叫做CAS的ABA问题

如何解决CAS的ABA问题

在上述取钱的过程中,之所以会出现ABA问题,是因为我们使用钱作为中间值来判断是否有线程穿插进行修改余额,这个余额是可加可减的,所以会出现ABA问题,如何解决呢,我们可以规定只能➕不能➖,从而规避这个问题,如何解决呢?引入一个"版本号"

我们规定版本号从1开始,没进行一次修改那版本号就要加1,还是取钱的例子,首先,我们去取出500块,虽然我们多按了几次产生了多个线程,因为版本号的问题,我们一开始取出了500块这个时候版本号是1,而碰巧这个时候老妈给我转了500块,版本号是2,这个时候虽然账户变成了1000块,但是因为之前的线程针对的是版本号,所以他们会去比较版本号为1的时候的余额,发现这个时候确实是500,不是1000,所以就退出,也就可以规避CAS的ABA问题

相关推荐
俩个逗号。。5 分钟前
Kotlin flow 详解
android·开发语言·kotlin
Escalating_xu29 分钟前
【Linux 网络编程】五种 I/O 模型与非阻塞 I/O:从“等数据”到正确处理 EAGAIN
java·linux·网络
程序猿乐锅1 小时前
万字详解Single-flight(单飞模式)
java·开发语言·分布式·后端·学习·single-flight
Java后端的Ai之路1 小时前
【AIAgent开发】-Agent工具封装成CLI(纯干货!!!)
java·javascript·人工智能·agent·cli
AntsData2 小时前
用 12K+ 条亚马逊评论信号,定位机械键盘下一版该改什么
java·大数据·计算机外设
code2cat2 小时前
【随笔】连续批处理:长短请求怎样在迭代之间补位
java·人工智能·后端·大语言模型·vllm
最强小杰2 小时前
DeepSeek V4 Flash + Codex CLI 接入教程:原生 Responses API 适配,从配置到跑通收藏这篇就够了(2026)
java·前端·python·ai
考研保研资料分享2 小时前
2022环境工程保研北师大:三校专业追问、论文贡献与择校复盘
面试
Flynn Liang2 小时前
Spring AI 2.0 深度解析:ChatClient、Advisor 链与 MCP——Java 工程师的 AI 落地最优解
java·人工智能·spring·大模型·架构设计·spring ai
灿飞2 小时前
Kotlin与Java虚拟机六:基础与类型系统:一切皆对象,但对象有代价
java·kotlin