【JavaEE初阶】CAS(比较和交换)

news2024/11/24 16:35:12

目录

🌲 什么是 CAS

🌳 CAS的应用

🚩 实现原子类

🚩 实现自旋锁

🎄 CAS 的 ABA 问题

🚩 什么是 ABA 问题

🚩 ABA 问题引来的 BUG

🚩 解决方案

🍀CAS相关面试题


🌲 什么是 CAS

CAS: 全称Compare and swap,字面意思:"比较并交换"

这是一条 cpu 指令,就可以完成比较和交换这样的一套操作,那么对于cpu的一条指令操作,我们知道这是"原子的",这就给我们编写线程安全的代码,打开了新世界的大门。

CAS的流程:

我们假设内存中的原数据V,旧的预期值A,需要修改的新值B。

  1. 比较 A 与 V 是否相等。(比较)

  2. 如果比较相等,将 B 写入 V。(交换)

  3. 返回操作是否成功

CAS就类似于我们之前讲的Synchronized关键字,都是将操作变为原子性,但是呢,CAS只适用于一些特殊场景,并不通用

CAS的好处:

  • 当多个线程同时对某个资源进行CAS操作,只能有一个线程操作成功,但是并不会阻塞其他线程,其他线程只会收到操作失败的信号。

关于CAS是属于我们讲的那一种锁策略?

我们可以将CAS 视为是一种乐观锁. (或者可以理解成 CAS 是乐观锁的一种实现方式

🌳 CAS的应用

🚩 实现原子类

标准库中提供了 java.util.concurrent.atomic 包, 里面的类都是基于这种方式来实现的.
典型的就是 AtomicInteger 类.

里面提供了很多方法可以供操作

其中的 getAndIncrement 相当于 i++ 操作.

代码:

这就是使用原子类代替了普通int的 i++,此处的代码是没有用到任务加锁操作,那么代码就没有阻塞等待,使代码以更高的效率来执行程序。通过形如上述代码就可以实现一个原子类. 不需要使用重量级锁, 就可以高效的完成多线程的自增操作.

🚩 实现自旋锁

自旋锁是基于 CAS 实现更灵活的锁, 获取到更多的控制权.

自旋锁的伪代码如下:

利用上述伪代码的思想就可以实现一个自旋锁了

CAS操作虽然好用,但是也存在一些问题

🎄 CAS 的 ABA 问题

🚩 什么是 ABA 问题

ABA问题:

属于 CAS 的一个重要注意事项。

假设存在两个线程 t1 和 t2. 有一个共享变量 num, 初始值为 A.

接下来, 线程 t1 想使用 CAS 把 num 值改成 Z, 那么就需要

  • 先读取 num 的值, 记录到 oldNum 变量中.

  • 使用 CAS 判定当前 num 的值是否为 A, 如果为 A, 就修改成 Z.

但是, 在 t1 执行这两个操作之间, t2 线程可能把 num 的值从 A 改成了 B, 又从 B 改成了 A

  • 线程 t1 的 CAS 是期望 num 不变就修改. 但是 num 的值已经被 t2 给改了. 只不过又改成 A 了. 这个时候 t1 究竟是否要更新 num 的值为 Z 呢?

到这一步, t1 线程无法区分当前这个变量始终是 A, 还是经历了一个变化过程

🚩 ABA 问题引来的 BUG

大部分的情况下, t2 线程这样的一个反复横跳改动, 对于 t1 是否修改 num 是没有影响的. 但是不排除一些特殊情况

接下来我为大家举一个例子:

滑稽老铁进行取款,在取款过程中,发生了bug,按了一下取款,卡了一下紧接着又按了一下取款,此时产生了两个线程来执行上述扣款操作

  • 我们期望一个线程执行 -500 成功,
  • 另一个线程 -500 失败.

此时的代码是没有问题的,我们来引入ABA场景。当我们在取钱的时候(t2扣款完毕),另一个人(t3)正好给滑稽老铁转了500.

  • t2扣款1000->500,t3转载 500->1000(ABA问题 A->B->A)

那么如果t1的执行逻辑在t3之后,此时看到的就是balance仍然是1000,那么t1中的比较就成立了,即t1又会扣款一次,导致取出来500,之际上余额扣了1000,这就是很严重的bug~~

🚩 解决方案

给要修改的值, 引入版本号. 在 CAS 比较数据当前值和旧值的同时, 也要比较版本号是否符合预期.

CAS 操作在读取旧值的同时, 也要读取版本号.

真正修改的时候

  • 如果当前版本号和读到的版本号相同, 则修改数据, 并把版本号 + 1.

  • 如果当前版本号高于读到的版本号. 就操作失败(认为数据已经被修改过了)

这就好比, 判定这个手机是否是翻新机, 那么就需要收集每个手机的数据, 第一次挂在电商网站上的手机记为版本1,以后每次这个手机出现在电商网站上, 就把版本号进行递增. 这样如果买家不在意这是翻新机, 就买. 如果买家在意, 就可以直接略过

我们再来利用版本号来解决一下滑稽老铁的问题

  • 假设 滑稽老铁 有 1000 存款.滑稽老铁想从 ATM 取 500 块钱. 取款机创建了两个线程, 并发的来执行 -500操作.我们期望一个线程执行 -500 成功, 另一个线程 -500 失败.为了解决 ABA 问题, 给余额搭配一个版本号, 初始设为 1.
  1. 存款 1000. 线程1 获取到 存款值为 1000, 版本号为 1, 期望更新为 500; 线程2 获取到存款值为 1000,版本号为 1, 期望更新为 500.
  2. 线程1 执行扣款成功, 存款被改成 500, 版本号改为2. 线程2 阻塞等待中.
  3. 在线程2 执行之前,滑稽的朋友正好给滑稽转账 500, 账户余额变成 1000, 版本号变成3.
  4. 轮到线程2 执行了, 发现当前存款为 1000, 和之前读到的 1000 相同, 但是当前版本号为 3, 之前读到的版本号为 1, 版本小于当前版本, 认为操作失败.

取款:

存款:

在 Java 标准库中提供了 AtomicStampedReference 类. 这个类可以对某个类进行包装, 在内部就提供了上面描述的版本管理功能.关于 AtomicStampedReference 的具体用法此处不再展开

🍀CAS相关面试题

1.讲解下你自己理解的 CAS 机制

全称 Compare and swap, 即 “比较并交换”. 相当于通过一个原子的操作, 同时完成 “读取内存, 比 较是否相等,修改内存” 这三个步骤. 本质上需要 CPU 指令的支撑

2.ABA问题怎么解决?

给要修改的数据引入版本号. 在 CAS 比较数据当前值和旧值的同时, 也要比较版本号是否符合预期. 如果发现当前版本号和之前读到的版本号一致, 就真正执行修改操作, 并让版本号自增; 如果发现当 前版本号比之前读到的版本号大, 就认为操作失败

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1995390.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

自动化测试客户端程序 时,选择使用什么自动化测试工具?

自动化测试客户端程序时,可以选择多种自动化测试工具,这些工具根据测试的具体需求、目标平台以及开发语言等因素有所不同。以下是一些常用的自动化测试工具,它们分别适用于不同的测试场景: 1. Appium 简介:Appium是一…

你要动态建表,还要动态导入Excel?

背景 ⭐⭐⭐⭐⭐转载请注明出处:https://juejin.cn/post/7400945359192866828 前几天和公司的小伙伴聊天的时候,得知他们的项目里正要做一个功能。大概就是每家公司都会建一张表,这张表会有什么字段不确定,可能有的表10个字段,有的8个字段。然后会有导入的功能,就是给这张…

java实现解析pdf格式发票

为了减少用户工作量及误操作的可能性&#xff0c;需要实现用户上传PDF格式的发票&#xff0c;系统通过解析PDF文件获取发票内容&#xff0c;并直接将其写入表单。以下文章记录了功能实现的代码。 发票样式 发票内容解析 引用Maven 使用pdfbox <dependency><groupI…

API可观察性对于现代应用程序的最大好处

API可观察性是提升性能、加速问题诊断和增强安全的关键。它在理解和管理错综复杂的API交互方面发挥着至关重要的作用。利用API可观察性&#xff0c;您可以深入洞察API的工作状态&#xff0c;保障服务的可靠性&#xff0c;并优化用户体验。 在当今的数字环境中&#xff0c;API …

kubernetes集群部署sql server数据库服务

背景&#xff1a; 因业务上线需要&#xff0c;研发中心要求在kubernetes测试集群部署一个sql server 2017的数据库&#xff0c;用于业务功能调试。 一、实施部署sql server数据库&#xff1a; 1、拉取sql server 2017的镜像&#xff1a; [rootharbor-02 ~]# docker pull mcr…

POI导出复杂Excel表格

记录在遇到复杂统计报表业务时&#xff0c;无法使用Excel模板生成对应报表&#xff0c;则采用最原始poi方式进行创建生成 业务所需统计报表如下图 麻烦所在各类型订单下方餐别为动态数据&#xff0c;废话不多说直接上代码 new CellRangeAddress(起始行号, 终止行号, 起始列号,…

Android Studio 设置打开layout.xml文件的默认视图split

Android Studio 设置打开layout.xml文件的默认视图 Android Studio 设置打开layout.xml文件的默认视图 androd studio 在使用的时候打开我们自己的布局文件默认展示的视图为Design,我们想要编辑的时候还有手动切换成splite 视图或者Code视图&#xff0c;不上很方便&#xff0c…

CA证书和openssl介绍

文章目录 一、加密和算法常见的安全攻击加密算法和协议对称加密非对称加密算法 二、CA和证书中间人攻击CA和证书安全协议SSL/TLS协议介绍HTTPS 三、opensslopenssl介绍使用openssl实现对称加密使用openssl命令生成加密密码生成随机密码建立私有CA证书申请颁发建立私有CA实际例子…

Java-数据库基本概念

数据库DataBase 定义: 保存一组数据的仓库就是数据库 例 BirdBoot项目中&#xff0c;我们为了保存一组用户信息&#xff0c;创建了一个目录users。里面用若干个文件保存每一个用户信息 此时users目录就可以称为是一个数据库 只不过对于这些数据的维护操作&#xff0c;要么…

【最多可以参加的会议数目】python刷题记录

R4-贪心篇 结束时间升序排列优先队列 class Solution:def maxEvents(self, events: List[List[int]]) -> int:dictdefaultdict(list)for i,val in enumerate(events):dict[val[0]].append(val[1])#优先队列&#xff08;小根堆&#xff09;h[]ret0for i in range(1,100001)…

C语言求平方和倒数

文章目录 1. 代码实现float类型数据double类型数据使用 double 类型的调整 2. 魔数与位级别操作浮点数表示位级别魔数操作 3. 牛顿迭代4. 复杂代码具体解释具体解释&#xff1a;目的&#xff1a;举例&#xff1a; 5.感谢 平方和倒数 广泛用于计算机图形学中&#xff0c;尤其是在…

Qt实现类似淘宝商品展示看板功能简版

前一篇文章的简化版本只有浏览功能&#xff0c;前一篇文章链接如下&#xff1a; Qt实现类似淘宝商品看板的界面&#xff0c;带有循环翻页以及点击某页跳转的功能 效果如下&#xff1a; 代码留给有需要的人。 #ifndef ModelDashboardGroup_h__ #define ModelDashboardGroup_…

DC-DC PCB 布线参考

在DC-DC芯片的应用设计中&#xff0c;PCB布板是否合理对于芯片能否表现出其最优性能有着至关重要的影响。不合理的PCB布板会造成芯片性能变差如线性度下降&#xff08;包括输入线性度以及输出线性度&#xff09;、带载能力下降、工作不稳定、EMI辐射增加、输出噪声增加等&#…

容量 动效 仪表盘 Canvas 2D API

容量动效 <!DOCTYPE html> <html lang"zh"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>Canvas 内部圆形波浪</title><…

【区块链+乡村振兴】基于区块链的农权抵押贷款平台 | FISCO BCOS应用案例

当前两权抵押贷款业务逐渐活跃&#xff0c;但因参与两权抵押的相关方独立运营各自的管理系统&#xff0c;办理农权抵押贷款业务时&#xff0c; 存在多方信息不对称、业务办理过程繁琐、低效等问题&#xff0c;且不利于相关部门对农权抵押情况进行监督管理。具体表现在&#xff…

《数据资产管理核心技术与应用》相关分享章节

【图书推荐】《数据资产管理核心技术与应用》-CSDN博客 图书《数据资产管理核心技术与应用》介绍-CSDN博客 本文用于快速了解数据资产管理的概念及其技术范围。 数据资产通常是指那些可以通过分析来揭示价值、支持企业决策制定、优化企业流程、预测行业的未来趋势或产生更大…

dhcp+checkkickstar的实验理解

文章目录 实验介绍使用的服务介绍PXE服务dhcp服务Kickstart 服务tftp服务 第一部分&#xff08;基础部分&#xff09;代码展示注意点第一点![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/13c0f4aabb664655a4dd285dd8e5527a.png)第二点 结果展示 第二部分&#xff08…

元岳食堂采购供应链系统-智慧食堂数据化解决方案

随着社会的发展和科技的进步&#xff0c;在数字化浪潮的推动下&#xff0c;智慧食堂供应链系统逐渐成为食堂管理的重要工具。在此背景下&#xff0c;元岳食堂采购供应链系统应运而生&#xff0c;该系统通过其独特的数字化和自动化功能&#xff0c;能够对食堂的采购、储存、配送…

重庆市合川区第二届网络安全“钓鱼城“杯部分题解

MISC 下载文件后&#xff0c;进行分析 往下划看见smb 最开始以为是通过smb协议下载的文件 找半天没发现&#xff0c;往前翻了翻&#xff0c;看见了flag 存储为原始数据 通过上述分析发现开头是pk&#xff0c;保存为zip压缩包 发现需要密码 感觉是伪加密 使用工具一把梭 再…

免费的GA/T1400视图库平台Easy1400软件又迭代出新版本了!

自从年初发布了这款免费的GA1400视图库平台&#xff08;https://blog.csdn.net/xiejiashu/article/details/135050381&#xff09;&#xff0c;本来就是想做一做能给大家差不多能用就行了&#xff0c;没成想总是忍不住要改一改、优化优化&#xff0c;于是又经过了几个月的优化&…