news 2026/7/14 13:28:56

Java并发基石——CAS是如何实现的?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Java并发基石——CAS是如何实现的?

目录

一. 什么是CAS?

二. Java中关于 CAS 的 API 在哪里?

三. CAS API方法和参数解析

四. CAS的底层实现

五. CAS是如何保证多核线程安全的?

六. CAS的缺点?

七. 如何避免ABA问题?


一. 什么是CAS?

CAS的全称是 "CompareAndSwap",翻译过来就是 "比较和替换"。

CAS的操作包含三个操作数——内存地址,期望值,新值。如果内存位置的值与期望值匹配,那么处理器就会自动将该位置的值更新为新值;否则,处理器不做任何操作。无论哪种情况,它都会在CAS指令之前返回该位置的值。

CAS可以理解为 "我认为位置V的值应该是A,如果有该值,则将B放在这个位置;否则,不更改该位置的值,只告诉我这个位置现在的值即可"。

二. Java中关于 CAS 的 API 在哪里?

Java中 CAS 的 API 方法定义在 sun.misc.Unsafe 类中,Unsafe(不安全的)。

如下图所示就是该类中的部分代码,圈出来的三个方法 ,三个方法都有 native 修饰,这些方法不是由 Java 语言编写的,而是由C语言编写的;总之记住一点就行了,这些 native 本地CAS方法是用C语言编写的,通常也不是让我们 Java 程序员去调用使用的,更多见到它们是在源码中碰到它们。

三. CAS API方法和参数解析

CAS的三个方法作用相似,它们都有四个参数,我来说一下它们的作用。

compareAndSwapObject:比较并交换 Object 类型数据;

compareAndSwapInt:比较并交换 Int 类型数据;

compareAndSwapLong:比较并交换 Long 类型数据;

var1:方法要操作的对象;

var2:方法要操作的对象中属性的偏移量(举个例子,我们有一个 User 用户对象,在堆中存放,但我们只获取该 User 对象的其中一个属性值,就需要通过偏移量来获取,例如 user.name 获取用户名称属性);

var3:表示想要修改的数据属性当前值(意思就是改之前是什么值);

var4:表示想要修改的数据的修改值(意思就是想改成什么值);

四. CAS的底层实现

CAS的底层实现是通过调用 JNI 代码来实现的。

JNI 全称 java.native.interface ,翻译过来就是 Java本地接口方法,允许Java调用其它语言,而Java中的这三个CAS方法底层是用C语言编写的,通过C语言调用底层CPU,最终映射到CPU指令集上得以实现。

五. CAS是如何保证多核线程安全的?

现在的计算机大多都是多核心处理器,那么在此种情况下,系统执行CAS操作之前,会先去判断当前系统是否为多核心系统。如果是,就会给 "总线" 加锁,尽管有多个线程,但只有一个线程能给总线加锁成功,加完锁之后就会去执行CAS操作,也就是说CAS操作的原子性是平台级别的。而且只能有一个线程在同一时刻能够去执行CAS运算,无法多线程并行CAS操作,这样就解决了多核线程的安全问题。

六. CAS的缺点?

上面说到了CAS的操作原理,比较并替换,CAS操作时需要先判断先前的值是否发生变化,未变化则CAS,变化了则不执行CAS,如果说A线程在执行CAS操作之前,B线程将需要判断的值 a 改为了 b ,然后又从 b 改成了 a。那么当A线程再去执行CAS操作的时候,是可以执行成功的,因为它不管中间过程,只要我线程A在CAS时值未发生变化,就可以替换,但不能避免发生过变化不影响操作这种情况的发生。

举个简单的例子,事务A要去对数据库中的字段 num (假设当前值为1)做加一操作,事务B在事务A之前先去执行了加一操作,值变成了2,但是执行过程中发生了异常,事务B回滚,又从2回滚到了1,此时事务A再去对 num 进行加一操作时,是可以成功的,因为值没有发生改变。这种情况我们通常称为ABA问题。

七. 如何避免ABA问题?

为了解决ABA问题,在Java中,就引入了版本号这一说法,很简单,我们执行CAS操作时,不是会比较当前值和期望值是否相同吗?那我们就再加入一个版本号,对当前可能出现ABA问题的数据加上一个版本号,每当有一个线程对当前数据发生过修改,版本号都会做一次变换,即便又改回了原来的值,版本号也是不一致的。这样我们在执行CAS操作时,不仅要满足为当前值与期望值相等,还要满足当前版本号与期望版本号相同,只要有一个不同,CAS操作就不会成功,这样就可以避免ABA问题的出现。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/14 13:28:21

ModTheSpire终极指南:5步快速上手《杀戮尖塔》模组加载器

ModTheSpire终极指南:5步快速上手《杀戮尖塔》模组加载器 【免费下载链接】ModTheSpire External mod loader for Slay The Spire 项目地址: https://gitcode.com/gh_mirrors/mo/ModTheSpire ModTheSpire是《杀戮尖塔》最强大的外部模组加载器,让…

作者头像 李华
网站建设 2026/7/14 13:26:41

Java 异常体系全面总结详解

目录 一. 什么是异常? 二. 异常家族体系介绍 2.1 Error 2.2 Exception 2.2.1 Exception 详情 2.2.2 运行时异常 2.2.3 编译时异常 2.2.4 Exception 分类总结 三. 从类加载的全过程深入理解编译时异常与运行时异常 3.1 类加载的全过程 3.2 什么是编译时异…

作者头像 李华
网站建设 2026/7/14 13:24:57

张量网络系列(二 从图解到缩并:张量网络的运算艺术)

1. 图解张量:从抽象符号到视觉直觉第一次接触张量网络时,我被那些带"腿"的圆圈图标彻底搞懵了——直到把矩阵乘法画成连线游戏才恍然大悟。图解表示法的神奇之处在于,它能把晦涩的数学符号变成乐高积木般的可视化组件。比如当你看到…

作者头像 李华
网站建设 2026/7/14 13:23:57

手动修改spire.pdf

温馨提示:经过测试spire.pdf8-9版本都可以按照这个步骤进行,测试12版本已经不行了这个步骤不行了 首先自己需要一个破解的spire,但是找了半天根本找不到,要么是没用的网站,要么是要付费,研究半天发现spire…

作者头像 李华
网站建设 2026/7/14 13:22:52

AiZynthFinder未来展望:AI在合成化学中的发展趋势

AiZynthFinder未来展望:AI在合成化学中的发展趋势 【免费下载链接】aizynthfinder A tool for retrosynthetic planning 项目地址: https://gitcode.com/gh_mirrors/ai/aizynthfinder 在当今化学研究领域,人工智能正以前所未有的速度改变着合成化…

作者头像 李华