一文理解CAS和自旋的区别(荣耀典藏版)
目录
一、自旋
二、CAS
三、什么是 ABA 问题
大家好,我是月夜枫,通常在面试的时候,或者在学习的时候,经常性的会遇到一些关于锁的问题,尤其是面试官会提出提问,你对锁了解的多么?你知道锁的原理么?等等问题,于是也就会有后续延伸出来的,你知道 CAS 么?你知道什么是自旋么?今天就分析其中的CAS和自旋的区别。
一、自旋
顾名思义,自旋可以理解为“自我旋转”,放到程序中就是"自我循环",比如while循环或者for循环。结合着锁来理解的话就是,先获取一次锁,如果获取不到锁,会不停的循环获取,直到获取到。不像普通的锁那样,如果获取不到锁就进入阻塞状态。
二、CAS
CAS 是什么,它的英文全称是 Compare-And-Swap,中文叫做“比较并交换”,它是一种思想、一种算法。
CAS算法有3个基本操作数:
内存地址V
旧的预期值A
要修改的新值B
在并发场景下,各个代码的执行顺序不能确定,为了保证并发安全,我们可以使用普通的互斥锁,比如Java的 synchronized, ReentrantLock等。而CAS的特点是避免使用互斥锁,当多个线程并发使用CAS更新同一个变量时,只有一个可以操作成功,其他都会失败。而且用CAS更新失败的线程并不会阻塞,会快速失败并返回一个失败的状态,允许你再次尝试。
而Compare-And-Swap(CAS)是一种原子操作,用于实现多线程环境下的同步和并发控制。其基本原理如下:
-
读取内存值:首先,CAS会读取内存中的一个变量的当前值。
-
比较内存值和预期值:接下来,CAS会将读取的值与预期值进行比较。如果两者相等,则说明内存中的值没有被其他线程修改。
-
如果相等,则将新值写入内存:在比较阶段,如果发现内存值与预期值相等,CAS会尝试将新值写入内存中。这个写入操作是原子的,即在这个过程中不会被其他线程中断。
-
如果写入成功,则操作完成;否则重复上述步骤:如果写入操作成功,CAS完成。如果写入操作失败,说明在比较和写入的过程中,内存值已经被其他线程修改,此时需要重新执行整个CAS操作。
CAS的基本原理就是利用比较和写入的原子性操作来实现对共享变量的原子操作,从而避免了传统锁机制中的死锁和线程阻塞问题。
自旋锁和CAS的关系是什么呢?
其实他们是两个不同的概念 自旋是一种锁优化的机制,在锁优化中『自旋锁』指线程空转重试获取锁,避免线程上下文切换带来的开销。
CAS是一种乐观锁机制,cas是通过比较并交换,失败的时候可以直接返回false不用自旋的获取。只是一般应用场景下,cas都会带有重试机制(while或者for实现空转,不断尝试获取)。
如果硬有关系,那么可以这样理解
自旋锁 = 循环+CAS
我们都知道了这个自旋锁和 CAS 的关系了,那么CAS 都有哪些缺点呢?
Compare-And-Swap (CAS) 的缺点包括:
-
自旋等待:CAS 在执行时会进行自旋等待,如果失败则需要重试,这会消耗处理器资源。
-
ABA 问题:CAS 只能检测到共享变量的值是否发生了变化,但无法检测到变量的值是否经历了类似 A->B->A 的变化,这可能导致一些意外的问题。
-
无法保证公平性:CAS 操作是非阻塞的,因此无法保证等待线程的公平性,可能导致某些线程长时间无法获得执行机会。
-
无法解决死锁:CAS 无法解决死锁问题,如果多个线程同时执行 CAS 操作,可能导致死锁的发生。
-
限制性:CAS 操作通常只能应用于单个变量,对于复杂的数据结构,需要额外的处理来实现原子操作。
总的来说,CAS 虽然具有高效的特点,但也存在着一些局限性和缺点。
既然我们说了这个 CAS 那么面试官不可避免的就会问到,既然你了解了 CAS ,那么你是不是也对 ABA 问题有了解呢?
三、什么是 ABA 问题
我们先来看什么是 ABA 的问题。
ABA问题是在分布式系统中常见的一种数据一致性问题。它的名称来源于三个操作:A(原始值)、B(第一个读取)、A(第二个读取)。ABA问题发生在一个线程T1读取了一个共享变量的值A,然后另一个线程T2修改了这个共享变量的值为B,然后又改回A,最后线程T1再次读取这个共享变量的值,发现仍然是A。在这种情况下,线程T1可能会错误地认为共享变量的值没有改变,从而导致数据不一致。
解决ABA问题的常见方案是使用版本号或者标记来跟踪数据的变化。通过在每次数据变化时增加版本号或者标记,可以避免ABA问题的发生。另外,使用CAS(Compare and Swap)操作也可以解决ABA问题,CAS操作会在更新变量时检查变量的值是否仍然是预期值,从而避免了ABA问题的发生。
简单的说就是
比如线程1从内存位置V中取出A,此时线程2也取出A。且线程2做了一次cas将值改为了B,然后又做了一次cas将值改回了A。此时线程1做cas发现内存中还是A,则线程1操作成功。这个时候实际上A值已经被其他线程改变过,这与设计思想是不符合的。
那么这个问题出现在哪里呢?
-
如果只在乎结果,ABA不介意B的存在, 没什么问题
-
如果B的存在会造成影响,需要通过 AtomicStampReference,加时间戳解 决。
那关于自旋和 CAS 你了解了么?
相关文章:

一文理解CAS和自旋的区别(荣耀典藏版)
目录 一、自旋 二、CAS 三、什么是 ABA 问题 大家好,我是月夜枫,通常在面试的时候,或者在学习的时候,经常性的会遇到一些关于锁的问题,尤其是面试官会提出提问,你对锁了解的多么?你知道锁的原…...

【吊打面试官系列】Java虚拟机JVM篇 - 关于内存溢出
大家好,我是锋哥。今天分享关于内存溢出的JVM面试题,希望对大家有帮助; 什么是内存溢出? 内存溢出(OOM)是指可用内存不足。程序运行需要使用的内存超出最大可用值,如果不进行处理就会影响到其他…...

思科网络中如何配置标准ACL协议
一、什么是标准ACL协议?有什么作用及配置方法? (1)标准ACL(Access Control List)协议是一种用于控制网络设备上数据流进出的协议。标准ACL基于源IP地址来过滤数据流,可以允许或拒绝特定IP地址范…...

蓝桥杯刷题(二)
参考大佬代码:(区间合并二分) import os import sysn, L map(int, input().split()) # 输入n,len arr [list(map(int, input().split())) for _ in range(n)] # 输入Li,Si def check(Ti, arr, L)->bool:sec [] # 存入已打开的阀门在…...

【Python】牛客网—软件开发-Python专项练习(day1)
1.(单选)下面哪个是Python中不可变的数据结构? A.set B.list C.tuple D.dict 可变数据类型:列表list[ ]、字典dict{ }、集合set{ }(能查询,也可更改)数据发生改变,但内存地址不变 不…...
P3405 [USACO16DEC] Cities and States S题解
题目 Farmer John有若干头奶牛。为了训练奶牛们的智力,Farmer John在谷仓的墙上放了一张美国地图。地图上表明了每个城市及其所在州的代码(前两位大写字母)。 由于奶牛在谷仓里花了很多时间看这张地图,他们开始注意到一些奇怪的…...

JavaScript原型和原型链
JavaScript每个对象拥有一个原型对象 需要注意的是,只有函数对象才有 prototype 属性 当试图访问一个对象的属性时,它不仅仅在该对象上搜寻,还会搜寻该对象的原型,以及该对象的原型的原型,依次层层向上搜索ÿ…...

PyTorch之完整的神经网络模型训练
简单的示例: 在PyTorch中,可以使用nn.Module类来定义神经网络模型。以下是一个示例的神经网络模型定义的代码: import torch import torch.nn as nnclass MyModel(nn.Module):def __init__(self):super(MyModel, self).__init__()# 定义神经…...

基于神经网络的偏微分方程求解器再度取得突破,北大字节的研究成果入选Nature子刊
目录 一.引言:神经网络与偏微分方程 二.如何基于神经网络求解偏微分方程 1.简要概述 2.基于神经网络求解偏微分方程的三大方向 2.1数据驱动 基于CNN 基于其他网络 2.2物理约束 PINN 基于 PINN 可测量标签数据 2.3物理驱动(纯物理约束) 全连接神经网路(FC-NN) CN…...

Linux的基本权限
一、对shell的浅显认识 shell是操作系统下的一个外壳程序,无论是Linux操作系统,还是Windows操作系统,用户都不会直接对操作系统本身直接进行操作,需要通过一个外壳程序去间接的进行各种操作 在Linux的shell外壳就是命令行&#…...

指纹加密U盘/指纹KEY方案——采用金融级安全芯片 ACH512
方案概述 指纹加密U盘解决方案可实现指纹算法处理、数据安全加密、数据高速存取(EMMC/TF卡/NandFlash),可有效保护用户数据安全。 方案特点 • 采用金融级安全芯片 ACH512 • 存储介质:EMMC、TF卡、NandFlash • 支持全系列国密…...

Cloud-Sleuth分布式链路追踪(服务跟踪)
简介 在微服务框架中,一个由客户端发起的请求在后端系统中会经过多个不同的服务节点调用来协同产生最后的请求结果,每一个前端请求都会形成一条复杂的分布式服务调用链路,链路中的任何一环出现高延时或错误都会引起整个请求最后的失败 GitHub - spring-cloud/spring-cloud-sl…...

flink重温笔记(十四): flink 高级特性和新特性(3)——数据类型及 Avro 序列化
Flink学习笔记 前言:今天是学习 flink 的第 14 天啦!学习了 flink 高级特性和新特性之数据类型及 avro 序列化,主要是解决大数据领域数据规范化写入和规范化读取的问题,avro 数据结构可以节约存储空间,本文中结合企业真…...

python75-Python的函数参数,关键字(keyword)参数
在定义Python函数时可定义形参(形式参数的意思)这些形参的值要等到调用时才能确定下来,由函数的调用者负责为形参传入参数值。简单来说,就是谁调用函数,谁负责传入参数值。 关键字(keyword)参数 Python函数的参数名不是无意义的,…...

Java宝典-抽象类和接口
目录 1. 抽象类1.1 抽象类的概念1.2 抽象类的语法1.3 抽象类的特点 2. 接口2.1 接口的概念2.2 接口的语法2.3 接口的特点2.4 实现多个接口2.5 接口的继承 3. 接口使用案例 铁汁们好,今天我们学习抽象类和接口~ 1. 抽象类 1.1 抽象类的概念 什么是抽象类?在面向对象中,如果一…...

6. Gin集成redis
文章目录 一:连接Redis二:基本使用三:字符串四:列表五:哈希六:Set七:管道八、事务九:示例 代码地址:https://gitee.com/lymgoforIT/golang-trick/tree/master/14-go-redi…...

DxO PureRAW:赋予RAW图像生命,打造非凡视觉体验 mac/win版
DxO PureRAW 是一款专为RAW图像处理而设计的软件,旨在帮助摄影师充分利用RAW格式的优势,实现更加纯净、细腻的图像效果。该软件凭借其强大的功能和易于使用的界面,成为了RAW图像处理领域的佼佼者。 DxO PureRAW 软件获取 首先,Dx…...

【MySQL | 第四篇】区分SQL语句的书写和执行顺序
文章目录 4.区分SQL语句的书写和执行顺序4.1书写顺序4.2执行顺序4.3总结4.4扩充:辨别having与where的异同?4.5聚合查询 4.区分SQL语句的书写和执行顺序 注意:SQL 语句的书写顺序与执行顺序不是一致的 4.1书写顺序 SELECT <字段名> …...

服务器又被挖矿记录
写在前面 23年11月的时候我写过一篇记录服务器被挖矿的情况,点我查看。当时是在桌面看到了bash进程CPU占用异常发现了服务器被挖矿。 而过了几个月没想到又被攻击,这次比上次攻击手段要更高明点,在这记录下吧。 发现过程 服务器用的是4090…...

嵌入式学习day34 网络
TCP包头: 1.序号:发送端发送数据包的编号 2.确认号:已经确认接收到的数据的编号(只有当ACK为1时,确认号才有用) TCP为什么安全可靠: 1.在通信前建立三次握手连接 SYN SYNACK ACK 2.在通信过程中通过序列号和确认号保障数据传输的完整性 本次发送序列号:上次…...
【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15
缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下: struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...

(二)TensorRT-LLM | 模型导出(v0.20.0rc3)
0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述,后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作,其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...
【解密LSTM、GRU如何解决传统RNN梯度消失问题】
解密LSTM与GRU:如何让RNN变得更聪明? 在深度学习的世界里,循环神经网络(RNN)以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而,传统RNN存在的一个严重问题——梯度消失&#…...

376. Wiggle Subsequence
376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...

(二)原型模式
原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...
使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装
以下是基于 vant-ui(适配 Vue2 版本 )实现截图中照片上传预览、删除功能,并封装成可复用组件的完整代码,包含样式和逻辑实现,可直接在 Vue2 项目中使用: 1. 封装的图片上传组件 ImageUploader.vue <te…...
Robots.txt 文件
什么是robots.txt? robots.txt 是一个位于网站根目录下的文本文件(如:https://example.com/robots.txt),它用于指导网络爬虫(如搜索引擎的蜘蛛程序)如何抓取该网站的内容。这个文件遵循 Robots…...
鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/
使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题:docker pull 失败 网络不同,需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...
高防服务器能够抵御哪些网络攻击呢?
高防服务器作为一种有着高度防御能力的服务器,可以帮助网站应对分布式拒绝服务攻击,有效识别和清理一些恶意的网络流量,为用户提供安全且稳定的网络环境,那么,高防服务器一般都可以抵御哪些网络攻击呢?下面…...
今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存
文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...