当前位置: 首页 > news >正文

CAS的超~详细介绍

什么是CAS

CAS全称Compare and swap,是一种比较特殊的CPU指令.  字面意思:"比较并交换",

一个CAS涉及到以下操作:

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

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

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

3.返回操作是否成功.

伪代码

下面写的代码不是原子的,真实的CAS是一个原子的硬件指令完成的.这个伪代码只是辅助理解CAS的工作流程.

boolean CAS(address, expectValue, swapValue) {if(&address == expectedValue) {&address = swapValue;return true;}return false;
}

其中,address表示内存地址,expectValue和swapValue表示寄存器中的值.

流程就是比较address内存地址中的值是否与expect寄存器中的值相同.如果相同,就把swap寄存器中的值和address中的值进行交换(说是交换,实际上是赋值,其实完了之后我们往往只关注内存中的值,寄存器中的值,就不需要了),返回true.     如果不同,无事发生,返回false. 

CAS是怎么实现的

针对不同的操作系统,JVM用到了不同的CAS实现原理(操作系统对指令进行封装,JVM又对操作系统提供的api又封装了一层.),简单来讲:

java的CAS利用的是unsafe这个类提供的CAS操作;(这样的操作,涉及到一些系统底层内容,使用不当,可能会带来风险,一般不建议直接用CAS)

unsafe的CAS依赖了的是jvm针对不同的操作系统实现的Atomic::cmpxchg

Atomic::cmpxchg的实现使用了汇编的CAS操作,并使用cpu硬件提供的lock机制保证其原子性.

简而言之,是因为硬件予以支持,软件层面才能做到.

CAS有哪些应用

实现原子类

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

AtomicInteger atomicInteger = new AtomicInteger(0);
//相当于i++操作(但实际上只是一个指令,它天然是原子的)
atomicInteger.getAndIncrement();

伪代码实现:

class AtomicInteger {private int value;public int getAndIncrement() {int oldValue = value;//发现value与oldValue不同.意味着CAS之前另一个线程修改了value//通过该方式,能意识到被修改while ( CAS(value, oldValue, oldValue + 1) != true) {oldValue = value;}//发现value被修改过,就重新读取新的value到OldValue中return oldValue;}
}

假设两个线程同时调用getAndIncrement

1.两个线程都读取value的值到oldValue中.(oldValue是一个局部变量,在栈上.每个线程都有自己的栈) 

 

 2.线程1先执行CAS操作,由于oldValue和value的值相同,直接对value进行赋值.

注意:

CAS是直接读内存的,而不是操作寄存器.

CAS的读内存,比较,写内存是一条硬件指令,是原子的.

 

3.线程2再执行CAS操作,第一次CAS的时候发现oldValue和value不相等,不能进行赋值.因此需要进入循环.

在循环里重新读取value的值赋给oldValue 

 

4.线程2接下来第二次执行CAS,此时oldValue和value相同,于是直接执行赋值操作. 

 

5.线程1和线程2返回各自的oldValue的值即可.

通过形如上述代码就可以实现一个原子类.不需要使用重量级锁,就可以高效的完成多线程的自增操作. 

实现自旋锁

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

public class SpinLock {private Thread owner = null;public void lock() {//通过CAS看当前锁是否被某个线程持有.//如果这个锁已经被别的线程持有,那么就自旋等待.//如果这个锁没有被别的线程持有,那么就把owner设为当前尝试加锁的线程while(!CAS(this.owner, null, Thread.currentThread())) {//当owner不为null的时候,循环就会一直执行下去,通过这样的"忙等"来完成等待效果}//阻塞式的等.让线程不参与cpu调度了,此处自旋式的等,没有放弃cpu//不会参与到调度,也就没有了调度开锁了.但缺点就是消耗了更多的cpu       public void unlock() {this.owner = null;}}
}

CAS的ABA问题

什么是ABA问题

ABA的问题:

假设存在两个线程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是没有影响的.但是不排除一些特殊情况.

假设一个人有1000元存款,他想从中取出500块钱.

取钱的时候ATM卡了,按了一下没反应(t1),又按了一下(t2)还是没反应

按理来说这应该是正常的.

1.存款1000,线程1获取到当前存款值1000,期望更新为500;线程2获取到当前存款值1000,期望更新为500.

2.线程1执行成功.存款被改为500,线程2阻塞等待中.

3.轮到线程2执行了,发现当前存款为500,与之前读到的1000不同,执行失败.

但如果出现了极端情况:比如中间有人给你转了500.

这个时候线程2发现当前存款为1000,与1000相同,又扣款了一次.

这个时候,就被扣款了两次,这都是ABA问题搞的鬼!!

解决方案

1.约定数据的变化是单向的(只能增加或者只能减少),不是双向的(既能增加又能减少)

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

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

  (2)真正修改的时候,

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

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

相关面试题

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

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

2.ABA问题怎么解决

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

相关文章:

CAS的超~详细介绍

什么是CAS CAS全称Compare and swap,是一种比较特殊的CPU指令. 字面意思:"比较并交换", 一个CAS涉及到以下操作: 我们假设内存中的原数据为V,旧的预期值A,需要修改的新值B. 1.比较A和V是否相等(比较) 2.如果相等,将B写入V.(交换) 3.返回操作是否成功. 伪代码 下面…...

Scott用户数据表的分析

Oracle从入门到总裁:https://blog.csdn.net/weixin_67859959/article/details/135209645 如果想要知道某个用户所有的数据表: select * from tab; 此时结果中一共返回了四张数据表,分别为部门表(dept) ,员工表(emp&a…...

网络基础学习(3):交换机

1.交换机结构 (1)网线接口和后面的电路部分加在一起称为一个端口,也就是说交换机的一个端口就相当于计算机上的一块网卡。 如果在计算机上安装多个网卡,并让网卡接收所有网络包,再安装具备交换机功能的软件&#xff0…...

【软件测试学习笔记2】用例设计方法

1.能对穷举场景设计测试点(等价法) 等价类: 说明:在所有测试数据中,具有某种共同特征的数据集合进行划分 分类:有效等价类:满足需求的数据集合 无效等价类:不满足需求的数据集合 步…...

蓝桥杯 第三场 小白入门赛

召唤神坤 有意思🤔(ikun)。虽然是第一题但也要配得上神坤的身份。 思路1 枚举分母,选择一个数据结构来选出分母两侧最大的两个数做分子。2s常数大些也无碍。我选择好写的ST表 思路2 写两个 d p dp dp 分别表示 1 1 1 到 i…...

网络安全等级保护测评规划与设计

笔者单位网络结构日益复杂,应用不断增多,使信息系统面临更多的风险。同时,网络攻防技术发展迅速,攻击的技术门槛随着自动化攻击工具的应用也在不断降低,勒索病毒等未知威胁也开始泛滥。基于此,笔者单位拟进…...

Error: Cannot find module ‘vue-template-compiler‘ 问题解决

启动Vuepress项目时报了如下错误:Error: Cannot find module vue-template-compiler Error: Cannot find module vue-template-compiler Require stack: - /usr/local/lib/node_modules/vuepress/node_modules/vue-loader/lib/compiler.js - /usr/local/lib/node_…...

华为认证云计算专家(HCIE-Cloud Computing)--练习题

华为认证云计算专家(HCIE-Cloud Computing)–练习题 1.(判断题)华为云stack支持鲲鹏架构,业务可从X86过渡到鲲鹏。 正确答案:正确 2.(判断题)业务上云以后,安全方面由云服务商负责,客户自己不需要做任何防…...

【MATLAB】【数字信号处理】产生系统的单位冲激响应h(t)与H(z)零极点分布

一、实验目的与要求 产生h(t) 与H(z) 零极点分布 二、实验仪器 微机,仿真软件MATLAB 2022a 三、实验内容与测试结果 1.已知描述连续系统的微分方程为y(t)5y(t)6y(t)2x(t)8x(t) ,计算系统的单位冲激响应h(t) 程序如下: clear all; ts0;…...

实验五:动态路由配置

实验五:动态路由配置 1.RIP 配置 【实验名称】 RIP 路由协议配置 【实验目的】掌握路由器 RIP 路由协议的基本配置 【实验设备】路由器( 2 台)、计算机( 2 台)、配置电缆( 1 根)、 V…...

苍穹外卖学习----出错记录

1.微信开发者工具遇到的问题: 1.1appid消失报错: {errMsg: login:fail 系统错误,错误码:41002,appid missing [20240112 16:44:02][undefined]} 1.2解决方式: appid可在微信开发者官网 登录账号后在开发栏 找到 复制后按以下步骤粘贴即…...

如何实现图片压缩

文章目录 1、canvas实现图片压缩2、其他 1、canvas实现图片压缩 canvas 实现图片压缩,主要是使用 canvas 的drawImage 方法 具体思路 拿到用户上传的文件转成base64创建一个 Image,主要是获取到这个图片的宽度和高度创建一个 2D 的画布,画布…...

机器学习算法实战案例:时间序列数据最全的预处理方法总结

文章目录 1 缺失值处理1.1 统计缺失值1.2 删除缺失值1.3 指定值填充1.4 均值/中位数/众数填充1.5 前后项填充 2 异常值处理2.1 3σ原则分析2.2 箱型图分析 3 重复值处理3.1 重复值计数3.2 drop_duplicates重复值处理 3 数据归一化/标准化3.1 0-1标准化3.2 Z-score标准化 技术交…...

MongoDB高级集群架构设计

两地三中心集群架构设计 容灾级别 RPO & RTO RPO(Recovery Point Objective):即数据恢复点目标,主要指的是业务系统所能容忍的数据丢失量。RTO(Recovery Time Objective):即恢复时间目标&…...

C++中JSON与string格式互转

1、JSON-》string 操作步骤&#xff1a; 1、在C中新建一个json对象并赋值&#xff0c;然后将其转给char *data。 2、在使用 #include <json.h> 头文件时&#xff0c;通常是使用第三方库 jsoncpp。由于它不是标准库的一部分&#xff0c;所以需要从官网http://jsoncpp.sou…...

2023一带一路暨金砖国家技能发展与技术创新大赛 【企业信息系统安全赛项】国内赛竞赛样题

2023一带一路暨金砖国家技能发展与技术创新大赛 【企业信息系统安全赛项】国内赛竞赛样题 2023一带一路暨金砖国家技能发展与技术创新大赛 【企业信息系统安全赛项】国内赛竞赛样题第一阶段&#xff1a; CTF 夺旗项目1. CTF 夺旗任务一 命令注入任务二 SQL 注入 项目2. 序列化漏…...

【BBuf的CUDA笔记】十二,LayerNorm/RMSNorm的重计算实现

带注释版本的实现被写到了这里&#xff1a;https://github.com/BBuf/how-to-optim-algorithm-in-cuda/tree/master/apex 由于有很多个人理解&#xff0c;读者可配合当前文章谨慎理解。 0x0. 背景 我也是偶然在知乎的一个问题下看到这个问题&#xff0c;大概就是说在使用apex的…...

安装Mac提示安装无法继续,因为安装器已损坏

目录 事件起因报错原因 事件起因 有两台电脑&#xff0c;由于电脑1下载镜像文件很快&#xff0c;于是我先用电脑1下载这个大文件&#xff0c;然后安装openresty&#xff0c;电脑2用http链接下载这个大文件。电脑2安装中途就报安装无法继续,因为安装器已损坏。 报错原因 不知…...

脚本编程游戏引擎会遇到哪些问题

在游戏开发中&#xff0c;脚本编程已经成为了一种非常常见的方式&#xff0c;用来实现游戏逻辑和功能。但是脚本编程游戏引擎也可能会面临一些挑战和问题。下面简单的探讨一下都会遇到哪些问题&#xff0c;并且该如果做。 性能问题 脚本语言通常需要运行时解释执行&#xff0…...

什么软件可以做报表?

数据报表&#xff0c;是商业领域中不可或缺的一部分&#xff0c;它通过表格、图表等形式&#xff0c;将复杂的数据进行整理、分析并呈现出来&#xff0c;帮助用户更好地理解数据的趋势和关系。数据报表不仅展示了业务现状和趋势&#xff0c;还支持多种数据分析和挖掘功能&#…...

java_网络服务相关_gateway_nacos_feign区别联系

1. spring-cloud-starter-gateway 作用&#xff1a;作为微服务架构的网关&#xff0c;统一入口&#xff0c;处理所有外部请求。 核心能力&#xff1a; 路由转发&#xff08;基于路径、服务名等&#xff09;过滤器&#xff08;鉴权、限流、日志、Header 处理&#xff09;支持负…...

Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?

Golang 面试经典题&#xff1a;map 的 key 可以是什么类型&#xff1f;哪些不可以&#xff1f; 在 Golang 的面试中&#xff0c;map 类型的使用是一个常见的考点&#xff0c;其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)

文章目录 1.什么是Redis&#xff1f;2.为什么要使用redis作为mysql的缓存&#xff1f;3.什么是缓存雪崩、缓存穿透、缓存击穿&#xff1f;3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例

使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件&#xff0c;常用于在两个集合之间进行数据转移&#xff0c;如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model&#xff1a;绑定右侧列表的值&…...

1688商品列表API与其他数据源的对接思路

将1688商品列表API与其他数据源对接时&#xff0c;需结合业务场景设计数据流转链路&#xff0c;重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点&#xff1a; 一、核心对接场景与目标 商品数据同步 场景&#xff1a;将1688商品信息…...

最新SpringBoot+SpringCloud+Nacos微服务框架分享

文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的&#xff0c;根据Excel列的需求预估的工时直接打骨折&#xff0c;不要问我为什么&#xff0c;主要…...

Module Federation 和 Native Federation 的比较

前言 Module Federation 是 Webpack 5 引入的微前端架构方案&#xff0c;允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...

关于 WASM:1. WASM 基础原理

一、WASM 简介 1.1 WebAssembly 是什么&#xff1f; WebAssembly&#xff08;WASM&#xff09; 是一种能在现代浏览器中高效运行的二进制指令格式&#xff0c;它不是传统的编程语言&#xff0c;而是一种 低级字节码格式&#xff0c;可由高级语言&#xff08;如 C、C、Rust&am…...

dify打造数据可视化图表

一、概述 在日常工作和学习中&#xff0c;我们经常需要和数据打交道。无论是分析报告、项目展示&#xff0c;还是简单的数据洞察&#xff0c;一个清晰直观的图表&#xff0c;往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server&#xff0c;由蚂蚁集团 AntV 团队…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现企业微信功能

1. 开发环境准备 ​​安装DevEco Studio 3.1​​&#xff1a; 从华为开发者官网下载最新版DevEco Studio安装HarmonyOS 5.0 SDK ​​项目配置​​&#xff1a; // module.json5 {"module": {"requestPermissions": [{"name": "ohos.permis…...