预见猿份
主题
首页面试题模拟面试SQL练习在线工具关于我们老苗一对一私教学员评价
实战项目
零基础学习路线项目前置基础创新WMS项目Java微服务框架与实战云岚到家项目闪聚支付项目学成在线项目青橙电商项目JVM原理与实战调优分布式事务专题Java高频面试题MySQL从入门到精通达梦数据库从入门到实战MongoDB从入门到实战PostgreSQL从入门到实战TiDB从入门到实战Java数据结构与算法Java 并发编程(JUC)实战课程老苗一对一私教学员评价
blog我的会员
  • Java 并发编程(JUC)实战课程

    • 课程介绍
    • 01 多线程入门
    • 02 线程的常用方法
    • 03 线程池
    • 04 synchronized教程
    • 05 ReentrantLock教程
    • 06 读写锁
    • 07 JMM教程
    • 08 CAS教程
    • 09 wait&notify
    • 10 常用的并发集合
    • 11 异步任务控制
    • 12 常用并发工具







----- 到底线了 -----

第8章 CAS教程 ​

2.3 CAS ​

2.3.1 CAS是什么? ​

原子操作新思路 ​

什么是原子操作?

原子操作是执行过程中不被CPU中断的操作,原子操作不会出现多线程交替执行。

比如:

b++、a+=2不具有原子性,多线程在执行时会存在多线程交替执行。

int a=0 具有原子性。

如何将非原子操作实现原子操作?

使用synchronized即可实现:

synchronized(obj){
   b++;
}
synchronized(obj){
   a+=2;
}
1
2
3
4
5
6

b++代码处地临界区中被同步锁保护,多线程执行临界区的代码只能同步执行即串行执行。

有关synchronized实现原子操作的内容可以参考“原子性”章节。

synchronized同步锁也称为悲观锁,它认为总会有线程修改另一个线程的数据造成线程不安全,它将临界区加锁控制,多线程只允许串行执行,这样就保证了一个线程在执行代码的同时不会有线程去交替执行,但是使用悲观锁的性能不高。

有没有一种相比悲观锁方案性能高的实现原子操作的方案呢?

CAS是一种无锁技术,也被称为乐观锁技术。乐观锁认为总是不会有线程去修改另一个线程的数据,所以它在操作时无需使用同步锁即可实现原子操作。CAS依赖CPU的CAS指令在更新数据前先判断数据是否被其它线程修改,如果没有修改则更新。

CAS是什么? ​

CAS的全称是Compare And Set,即比较并设置(也称为Compare And Swap即比较并交换),CAS从名称上是两个操作(一个比较 一个设置),但它是原子操作,底层由CPU指令支持,将比较和设置实现原子操作。

下面的例子说明 了CAS的操作过程:

下边通过一个例子说明CAS的过程,开发中++操作用的较多,下图是CAS实现++的原子操作:

wechat_longscreenshot_2026-09-20_104324_305.png

1、取出期望值,比如求a++,首先取a此时的内存值0。

2、计算目标值,计算a+1的值为1,注意此值是基于a等于0计算得到。

3、调用CAS指令。

4、CAS指令:取出a的当前值和期望值比较,如果相等则用目标值替换当前值。

​ 如果a的期望值与当前值不一致则说明有其它线程将a的值已经更改,转到第一步重新执行。

上图中橙色为CAS指令执行过程,根据CAS的过程可知正确使用CAS的方法如下:

while(true){
    //取出期望值 
    //计算目标值
    //调用CAS方法
    //判断如果操作成功则退出,否则继续下一轮循环
    if(CAS方法(...)){
        break;
    }
}
1
2
3
4
5
6
7
8
9

所以:

CAS操作共需要两个参数:期望值、目标值,目标值是基于期望值计算得出,CAS指令执行时会取出当前内存值与期望值比较如果相等则用目标值更新当前值。

CAS应用场景 ​

CAS是一种无锁实现原子操作的技术,也被称为乐观锁,对于并发高且写多的场景来说,CAS失败的概率很大,会不断的循环执行,导致CPU开销增加。CAS的这种不断循环尝试的过程叫自旋,它会不断重试直到操作成功为止,所以CAS适合读多写少的场景。比如:成绩更正,成绩录入完成后因录入错误需要更正的频率是很少的。

悲观锁适用并发量不大且接受一定延迟的场景,比如:订单退费,非双十一时订单退费的并发量相比下单的并发量少很多,且退费有一定的延迟用户可以接受。

CAS性能 ​

CAS采用无锁技术,其性能高于synchronized同步锁,原因如下:

1、synchronized同步锁使线程串行执行,没有获得锁的线程会进入等待队列阻塞,阻塞解除发生线程切换,上下文切换会耗费性能。

2、通过上边的入门程序可知CAS操作不成功会不断重试直到成功为止,CAS大大减少线程上下文切换的几率。

注意:synchronized从jdk6开始优化,其性能有了很大的提高,所以不要认为synchronized有多么的差,在实际开发要根据应用场景选用适合的技术方案。

🔒关注公众号,免费阅读全文

请免费关注 预见猿份 公众号,发送:yjoffer.com,获取解锁密码

公众号二维码微信扫码关注

关注公众号回复获取密码后,在下方输入并点击解锁,本机后续再读无需重复输入。

← 07 JMM教程09 wait&notify →








如果发现文档内容有错误或排版错乱,请及时联系站长老苗修改,不胜感激。联系我们
关于我们 | 隐私政策 | 豫ICP备2026003386号-4 | 豫公网安备41010202004008号
目录

本页无章节