对CAS的理解

news2025/1/16 21:06:54

CAS的概念(compare and swap):比较并交换

我们首先要明白,自旋是一个纯用户态的操作,本身并没有进行加锁,所执行的代码,是在并发环境下执行的,没有锁。

我们举一个例子来说明自旋加CAS的作用:

我们画一个时间图来接着证明:

线程中的Load和CAS的load并不一样,线程中的Load是获取预期值,而CAS中的load是在主内存中获取值,与预期值进行比较,两者作用并不相同。我们发现CAS并不是一个操作,首先要进行预期值和主内存中的值的比较,如果相同再进行下一步的操作,不相同则重新自旋+CAS,伪代码如下,按理说应该对应着许多条cpu指令,但是事实上它只对应着一条cpu指令(cmpxchg),一条指令可以完成所有操作,这条指令对应着系统的一个API,这个API有三个参数:地址值,预期值和要修改的值,但是我们必须要明白的是CAS的实现是通过cpu硬件提供的lock机制保证其原子性,简而言之就是因为硬件层面给予了支持,软件层面才能达到。

注意:CAS最重要的是判断我们第一次获取到的预期值和主内存中的值是否一致,也就是说数据是否在我们获取完预期值之后被其他线程修改过,没有修改过我们在此基础上进行的修改和写回操作是线程安全的,如果被修改过,此时我们再进行的修改和写回操作可能覆盖之前修改的值,这是线程不安全的。

CAS的两个应用:

①实现自旋锁:

伪代码如下:

②实现原子类

我们关于原子类的代码如下:

public class demo1001 {
    public static void main(String[] args) throws InterruptedException {
        //创建基于CAS的原子类
        AtomicInteger atomicInteger = new AtomicInteger();
        //创建两个线程实现自增操作
         Thread t1 =new Thread(()->{
             for (int i = 0; i <50000 ; i++) {
                 atomicInteger.getAndIncrement();
             }
                 });
         Thread t2 =new Thread(()->{
             for (int i = 0; i <50000 ; i++) {
                 atomicInteger.getAndIncrement();
             }
                 });
         //两个线程均开始执行
        t1.start();
        t2.start();
        //等待两个线程均执行结束
        t1.join();
        t2.join();
        System.out.println(atomicInteger);
    }
}

在这段代码中,我们并没有使用synchronized进行上锁,但是结果仍然是正确的

我们查看其源码:

关于CAS中的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是否要更新值为Z呢?

那在实际生活中我们举这样一个例子:

虽然从值的大小来看虽然是一样的,但是从操作过程和逻辑上来说有着很大的区别,可以说是两个完全不同的结果,那么我们又该如何解决这个ABA问题呢?

答案很简单,增加一个版本号,当有人对这个数据操作之后,该数据的版本号加1,虽然结果一致,但是我们可以通过版本号来判断这个结果是否是我们期望的结果

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

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

相关文章

Day05 C++STL入门基础知识三——String容器(上)概念-构造-赋值-拼接-查找-替换【全面深度剖析+例题代码展示】

文章目录1. 基本概念1.1 本质1.2 string与char*的区别1.3 特点2. 构造函数2.1 四种构造2.2 举例展示3. 赋值操作3.1 七种赋值函数原型&#xff08;operator等号赋值/assign成员函数赋值&#xff09;3.2 举例展示4. 拼接操作4.1 七种拼接函数原型4.2 举例展示5. 查找操作5.1 八种…

分布式概念

目录一、什么是分布式二、分布式与集群的关系三、软件架构演变四、RPC是什么1.RPC思想原理2.服务之间的交互可以用两种方式五、分布式思想与基本概念1.高并发2.高可用3.注册中心4.负载均衡5.服务雪崩6.熔断7.限流8.API网关9.服务跟踪10.弹性云一、什么是分布式 《分布式系统原…

Python流程控制语句之循环语句

上一篇&#xff1a;Python流程控制语句之选择语句 文章目录前言一、while 循环二、for 循环1. 进行数值循环2. 遍历字符串三、循环嵌套总结前言 生活中很多问题都无法一次解决&#xff0c;就像谚语所说&#xff1a;罗马不是一天建成的。一些事物必须周而复始地运转才能保证其存…

linux并发控制详解

目录 1.并发控制 1.1.并发概念 1.2.并发问题 2.多CPU核心 3.解决 4.中断屏蔽 5.原子操作 6.自旋锁 7.自旋锁衍生读写自旋锁 7.1.自旋锁与读写自旋锁的对比&#xff1a; 8.读写自旋锁衍生顺序锁 9.RCU 10.信号量 11.互斥体&#xff08;互斥锁&#xff09; 11.1.互…

2023起点上,一段迷茫的自我倾诉

大家新年快乐。 回顾记忆中渐渐远去的2022。 我曾想象随着一年过去我就能取得很大的进步&#xff0c;“彻底”改变自己的生活状态。其实不过幻想罢了&#xff0c;人才不会无缘无故进步呢。 我曾一度沉溺于网络世界中的关注&#xff0c;想象着自己将可以取得一些成就&#xff…

【每日一道智力题】三个火枪手(快来看人生哲理)

&#x1f680;write in front&#x1f680; &#x1f4dc;所属专栏&#xff1a; &#x1f6f0;️博客主页&#xff1a;睿睿的博客主页 &#x1f6f0;️代码仓库&#xff1a;&#x1f389;VS2022_C语言仓库 &#x1f3a1;您的点赞、关注、收藏、评论&#xff0c;是对我最大的激励…

Qt 之 QSystemTrayIcon

文章目录一、QSystemTrayIcon是什么二、属性三、公共类型四、信号提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 一、QSystemTrayIcon是什么 QSystemTrayIcon类为应用程序在系统托盘中提供一个图标。 如下图&#xff1a; 现代操作系统通常在桌面上提…

“深度学习”学习日记。与学习有关的技巧--Bacth Normalization

2023.1.25 现在已经学习过了&#xff0c;如果我们设置了合适的权重初始值&#xff0c;则各层的激活值分布会呈现适当的广度&#xff0c;从而可以时神经网络模型顺利的进行学习。 而 batch normalization算法 的思想就是为了使得各层有适当的广度&#xff0c;“强制性”地调整…

No package ‘vips‘ found系列问题解决方案

目录 系列报错集合 错误1 错误2 错误3 解决方案清单 系列报错集合 错误1 No package vips found Package vips was not found in the pkg-config search path. Perhaps you should add the directory containing vips.pc to the PKG_CONFIG_PATH environment variable N…

医疗实体及关系识别挑战赛

赛题概要 请本赛题排行榜前10的队友通过作品提交源代码&#xff0c;模型以及说明文档&#xff0c;截止时间为09/27/23:59:59.若文件过大&#xff0c;可发送至官网邮箱&#xff1a;AICompetitioniflytek.com。若截止时间内未提交&#xff0c;官方回通过电话联系相关选手&#x…

JavaEE8-Bean的生命周期

目录 1.Bean执行原理分析 2.Bean生命周期 2.1.实例化Bean&#xff1a;为Bean分配内存空间。&#xff08;相当于买房&#xff0c;从无到有&#xff09; 2.2.设置属性&#xff1a;Bean注入和装配。&#xff08;执行依赖类的注入&#xff1a;A需要使用B的方法&#xff0c;先初…

win32com操作word API精讲 第六集 Range(四)对齐和缩进

本课程《win32com操作word API精讲&项目实战》同步在B站、今日头条、视频号及本公众号发布。其中本平台以发布文字教程为主&#xff0c;所有平台ID均为&#xff1a;一灯编程 今天是大年初二&#xff0c;一灯在此祝愿各位朋友兔年吉祥&#xff0c;达成所想。 本节课主要讲解…

机器学习(六):模型评估

文章目录 模型评估 一、分类模型评估 二、 回归模型评估 三、拟合 1、欠拟合 2、过拟合 模型评估 模型评估是模型开发过程不可或缺的一部分。它有助于发现表达数据的最佳模型和所选模型将来工作的性能如何。 按照数据集的目标值不同&#xff0c;可以把模型评估分为分类…

Python信用卡欺诈检测 [TensorFlow]

Python信用卡欺诈检测 [TensorFlow] 提示&#xff1a;前言 Python 信用卡欺诈检测 提示&#xff1a;写完文章后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录Python信用卡欺诈检测 [TensorFlow]前言一、导入包二、加载数据三、加载数据四、 …

WebAssembly编译之(1)-asm.js及WebAssembly原理介绍

WebAssembly介绍及产生历程 1、什么是WebAssembly、为什么WASM&#xff1f; 我们知道Web的应用几乎涵盖了大半个互联网应用&#xff1b;越多越多的Web应用层出不穷&#xff0c;而然Web最致命的劣势就是其在浏览其的运行效率特忙&#xff0c;尤其是web游戏的体验不佳。 而Web…

ubuntu安装Espeak实现tts文字转语音

目录参考一、介绍二、安装安装包安装查看安装版本和espeak-data路径直接尝试安装中文包三、生产wav文件四、代码引入参考 ubuntu完美安装espeak支持中文和粤语 不再报错:Full dictionary is not installed for ‘zh’ 一、介绍 **用途&#xff1a;**可识别多语言的朗读软件 …

JavaEE day4 初识CSS

HTML如果说是前端网页中的骨架 那么CSS就是用来对骨架进行排版美化的、 CSS全称为 Cascading Style Sheets 层叠样式表 预备知识&#xff1a; html中的所有元素都有两个通用的属性&#xff1a;id和class id&#xff1a;唯一标识符&#xff0c;一个html组成元素中&#xff…

Day07 C++STL入门基础知识四——vector容器(上) 基本概念-构造函数-赋值操作-容量大小【全面深度剖析+例题代码展示】

Leave no stone unturned. 竭尽全力 文章目录1. 基本概念1.1 功能1.2 与普通数组相同点与不同点1.3 动态扩展2. 构造函数2.1 功能描述2.2 函数原型2.3 代码展示3. 赋值操作3.1 函数原型3.2 代码展示4. 容量及大小4.1 函数原型4.2 代码展示4.2.1 empty()4.2.1.1 代码展示4.2.1.2…

恶意代码分析实战 1 静态分析基础技术

1.1 Lab 1-1 对Lab01-01.exe和Lab01-01.dll进行分析 问题 将文件上传至http://www.VirusTotal.com进行分析并查看报告。文件匹配到了已有的反病毒软件特征吗? 首先查看Lab-01-01.exe。 然后查看Lab01-01.dll。 这两个文件应该都是恶意文件。 这些文件是什么时候编译的?…

20230125英语学习

Office Buzzwords You’re Using That Annoy All Your Co-workers 说话之道&#xff1a;避开办公室行话的“雷区” Joining a new office means having to learn how to communicate with your team.But in order to do that well, it sometimes means having to learn your …