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

自旋锁与CAS

上文我们认识了许许多多的锁,此篇我们的CAS就是从上文的锁策略开展的新概念,我们来一探究竟吧

1. 什么是CAS?

CAS: 全称Compare and swap,字⾯意思:“比较并交换”,⼀个CAS涉及到以下操作:
我们假设内存中的原数据V,旧的预期值A,需要修改的新值B。

  1. 比较A与V是否相等。(比较)
  2. 如果比较相等,将B写入V。(交换)
  3. 返回操作是否成功。

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

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

说明:

  1. address: 表示要修改的内存地址
  2. expectValue: 预期值
  3. swapValue:要设置的新值

执行流程:

  1. 用一个预期值去和内存中的值做比较
  2. 如果预期值与内存中的值相等,就用新的值更新内存中的值
  3. 如果预期值与内存中的值不相等,就用进入下一次比较

我们前面学习过的线程安全问题是由于CPU的随机调度导致的,我们的处理方法是给有关修改共享变量的代码块加了synchronize关键字,保证了原子性,解决了线程安全问题,
那么问题来了,
为什么我们看到的CAS伪代码并没有保证原子性,那么他是如何保证原子性的呢??

我们从一段例子来讲解:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

总结:

  1. CAS对应的是硬件指令cmpxchg从CPU做了原子性支持,与LOCK 、UNLOCK 指令同地位
  2. CAS操作每次读取(LOAD)数据是从主内存中读取,并没有对应的工作内存
  3. 自旋锁是通过while把CAS进行包裹,让CAS没有成功的时候不停的执行,直到成功执行为止
  4. CAS是一个真正的指令,JVM调用了本地方法之后,对应的CAS指令会在CPU上执行
    执行中LOAD数据会访问主内存

2. CAS实现自旋锁

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

public class SpinLock {private Thread owner = null;public void lock(){// 通过CAS 看当前锁是否被某个线程持有.  
// 如果这个锁已经被别的线程持有, 那么就⾃旋等待.  
// 如果这个锁没有被别的线程持有, 那么就把owner 设为当前尝试加锁的线程.  
}}while(!CAS(this.owner, null, Thread.currentThread())){}public void unlock (){this.owner = null;}

3. JDK中基于CAS实现的原子类

说明:

  1. JDK中提供了CAS实现的原子类,我们举其中一种AtomicInteger类来说明
    在这里插入图片描述
  2. 我们调用其中的方法getAndIncrement()
//自增 ++i
atomicInteger.getAndIncrement();
  1. 我们发现getAndIncrement()方法本质是getAndIncrement()
public final int getAndIncrement() {return U.getAndAddInt(this, VALUE, 1);
}
  1. 其中调用了Unsafe这个类的方法,是JDK内部的工具类,不建议外部程序员直接调用
private static final Unsafe U = Unsafe.getUnsafe();
//获取内存中字段在对象中的偏移地址private static final long VALUE= U.objectFieldOffset(AtomicInteger.class, "value");
//1. o表示原子类对象
//2. offset表示内存中字段在对象中的偏移地址
//3. delta表示传入的值
public final int getAndAddInt(Object o, long offset, int delta) {int v;do {//v是CAS操作之前获取的预期值v = getIntVolatile(o, offset);} while (!weakCompareAndSetInt(o, offset, v, v + delta));//while不停的自旋return v;}
   public final boolean weakCompareAndSetInt(Object o, long offset,//内存地址int expected,//预期值int x) {//要设置的值return compareAndSetInt(o, offset, expected, x);//最后调用compareAndSetInt()方法}
//native表示本地方法,即对应了一条CAS指令cmpxchg
public final native boolean compareAndSetInt(Object o, long offset,int expected,int x);
  1. 图解如下:
    在这里插入图片描述

4. CAS的ABA问题

首先我们要知道什么是ABA问题???

ABA的问题:
假设存在两个线程t1和t2.有一个共享变量value,初始值为A.
接下来,线程t1想使用CAS把value值改成Z,那么就需要
先读取value的值,记录到oldValue变量中.
使用CAS判定当前value的值是否为A,如果为A,就修改成Z.
但是,在t1执行这两个操作之间,t2线程可能把value的值从A改成了B,又从B改成了A

举个例子: 今天是疯狂星期四,我和我的女友共用一个小荷包吃饭,我和她说如果小荷包里面有100元 (A状态) 晚上6点就点KFC吃,我怕她忘记了,我就先自己点了,此时,小荷包余额为50元 (B状态) 然后我的朋友疯狂星期四V我50,小荷包的钱又变回了100 (A状态),她再点的时候,发现小荷包还是100元,她就再点了一份,就导致多点了一份KFC

那么我们该如何解决ABA问题呢??
在点KFC的例子当中,我们可以让他查看一下消费记录(版本号),此时的100元是否是开始的100元,
由此可得,我们可以可以给value数据加上一个版本号,当线程2要修改时,不仅要value要符合预期值,同时版本号也要符合
即:
CAS操作在读取旧值的同时,也要读取版本号.
真正修改的时候,

  • 如果当前版本号和读到的版本号相同,则修改数据,并把版本号+1.
  • 如果当前版本号高于读到的版本号.就操作失败(认为数据已经被修改过了).

版本号可以用自增的数值,也可以用随机的UUID,也可以使用时间戳

System.out.println(UUID.randomUUID());

生成随机数:
在这里插入图片描述

相关文章:

自旋锁与CAS

上文我们认识了许许多多的锁,此篇我们的CAS就是从上文的锁策略开展的新概念,我们来一探究竟吧 1. 什么是CAS? CAS: 全称Compare and swap,字⾯意思:“比较并交换”,⼀个CAS涉及到以下操作: 我们假设内存中…...

数组-二分查找

目录 算法思想: 实践: 备注: 二分查找是一种高效的查找算法,适用于在 有序数组 或列表中快速定位目标元素的索引。 重要事情说三遍:使用前提:数组有序,无重复,如果数组未排序&am…...

如何使用 Python 进行文件读写操作?

大家好,我是 V 哥。今天的内容来介绍 Python 中进行文件读写操作的方法,这在学习 Python 时是必不可少的技术点,希望可以帮助到正在学习 python的小伙伴。 以下是 Python 中进行文件读写操作的基本方法: 一、文件读取&#xff1…...

springcloud中的Feign调用

目录 一、基础应用 1.feign使用 1.增加feign依赖 2.编写feign接口 3.启用feign 4.调试 5.可能出现的异常信息 1.404 可能原因: 2.503 可有原因: 2.feign自定义配置 1.创建Feign配置类 2.feign接口 3.调试结果 3.feign多参数请求 Feign是Netflix开发的声明…...

【部署】将项目部署到云服务器

目录 1.获得服务器 2.连接到云服务器 3.配置环境 3.1.Java(运行后端所需) 3.2.MySQL数据库 3.3.Nginx(运行前端所需) 3.4. Node.js(构建前端所需) 4.打包项目 4.1.打包后端项目 4.2.打包前端项目…...

2024年AI大模型技术年度总结与应用实战:创新与突破并进

前言 回顾2024年,我一共发布了286篇博文,粉丝数也达到了43000多。这一年里,我收获颇丰,始终坚持AI大模型的研究方向,并且积极开展大模型的实战应用,也取得了一系列令人振奋的突破。 在286篇博文中&#…...

docker离线安装及部署各类中间件(x86系统架构)

前言:此文主要针对需要在x86内网服务器搭建系统的情况 一、docker离线安装 1、下载docker镜像 https://download.docker.com/linux/static/stable/x86_64/ 版本:docker-23.0.6.tgz 2、将docker-23.0.6.tgz 文件上传到服务器上面,这里放在…...

SuperdEye:一款基于纯Go实现的间接系统调用执行工具

关于SuperdEye SuperdEye是一款基于纯Go实现的间接系统调用执行工具,该工具是TartarusGate 的修订版,可以利用Go来实现TartarusGate 方法进行间接系统调用。 该工具的目标是为了扫描挂钩的NTDLL并检索Syscall编号,然后使用它来执行间接系统调…...

PCL 新增自定义点类型【2025最新版】

目录 一、自定义点类型1、前言2、定义方法3、代码示例二、合并现有类型三、点云按时间渲染1、CloudCompare渲染2、PCL渲染博客长期更新,本文最近更新时间为:2025年1月18日。 一、自定义点类型 1、前言 PCL库自身定义了很多点云类型,但是在使用的时候时如果要使用自己定义的…...

Docker导入镜像

使用命令行进行处理&#xff1a; docker load < onething1_wxedge.tar如下图所示 查看状态 docker images...

PyTorch使用教程(9)-使用profiler进行模型性能分析

1、简介 PyTorch Profiler是一个内置的性能分析工具&#xff0c;可以帮助开发者定位计算资源&#xff08;如CPU、GPU&#xff09;的瓶颈&#xff0c;从而更好地优化PyTorch程序。通过捕获和分析GPU的计算、内存和带宽利用情况&#xff0c;能够有效识别并解决性能瓶颈。 2、原…...

SpringBoot中使用MyBatis-Plus详细介绍

目录 一、MyBatis-Plus的使用步骤 1.引入MybatisPlus的起步依赖 2.定义Mapper&#xff08;也叫dao&#xff09;层的接口 3.MyBatis-Plus中常用注解 4. 使用MyBatis-Plus时要做如下配置 5.条件构造器 Wrapper 一、MyBatis-Plus的使用步骤 1.引入MybatisPlus的起步依赖 M…...

PCL 部分点云视点问题【2025最新版】

目录 一、问题概述二、解决方案1、软件实现2、代码实现三、调整之后博客长期更新,本文最近更新时间为:2025年1月18日。 一、问题概述 针对CloudCompare软件处理过的pcd格式点云,在使用PCL进行特征点提取、配准等实验中最终显示结果出现点云位置偏差较大的问题,本博客给出解…...

【Linux】常见指令(三)

Linux常见指令 01.nano02.cat03.cp04.mv 我的Linux专栏&#xff1a;【Linux】 本节Linux指令讲解的基本框架如下&#xff1a; 大家可以根据自己的需求&#xff0c;自行进行跳转和学习&#xff01; 01.nano nano Linux 系统中一款简单易用的命令行文本编辑器&#xff0c;适合…...

第5章:Python TDD定义Dollar对象相等性

写在前面 这本书是我们老板推荐过的&#xff0c;我在《价值心法》的推荐书单里也看到了它。用了一段时间 Cursor 软件后&#xff0c;我突然思考&#xff0c;对于测试开发工程师来说&#xff0c;什么才更有价值呢&#xff1f;如何让 AI 工具更好地辅助自己写代码&#xff0c;或许…...

nuxt3项目打包部署到服务器后配置端口号和开启https

nuxt3打包后的项目部署相对于一般vite打包的静态文件部署要稍微麻烦一些&#xff0c;还有一个主要的问题是开发环境配置的.env环境变量在打包后部署时获取不到&#xff0c;具体的解决方案可以参考我之前文章 nuxt3项目打包后获取.env设置的环境变量无效的解决办法。 这里使用的…...

MongoDB文档查询

一、实验目的 1. 理解MongoDB文档数据库的基本概念和特性。 2. 掌握在MongoDB中创建集合和插入文档数据的方法。 3. 学习使用MongoDB进行文档查询操作&#xff0c;包括查询、过滤和排序等。 二、实验环境准备 1. JAVA环境准备&#xff1a;确保Java Development Kit (J…...

【GORM】初探gorm模型,字段标签与go案例

GORM是什么&#xff1f; GORM 是一个Go 语言 ORM&#xff08;对象关系映射&#xff09;库&#xff0c;它让我们可以使用结构体来操作数据库&#xff0c;而无需编写SQL 语句 GORM 模型与字段标签详解 在 GORM 中&#xff0c;模型是数据库表的抽象表示&#xff0c;字段标签&am…...

Windows下的Milvus安装秘籍:向量数据库轻松上手

目录 一、简介 二、dockers的安装 1.介绍 2.环境准备 1.启动WSL 的功能。 2.安装并启动Hyper-V Windows10下的安装办法&#xff1a; Windows11下的安装办法&#xff1a; 启动Hyper-V 3.Docker的安装 4、验证是否安装成功 三、安装Milvus 1.Milvus下载 2.Milvus启动…...

在GUI中添加一个Label

标签是一种非常简单的小部件,它可以为我们的图形用户界面(GUI)增添价值。它可以阐释其他组件的用途,提供一些额外的信息,这可以引导用户理解输入框组件的含义,也能够解释那些无需用户输入数据的组件所显示数据的含义。 准备就绪 我们将扩展第一个应用案例,即《创建第一…...

django基于深度学习的音乐推荐系统_7182nd2n_zl035

前言随着数字音乐时代的到来&#xff0c;人们可以轻松访问数百万首歌曲。然而&#xff0c;如何在海量音乐中找到自己喜欢的音乐成为了一个挑战。基于Django框架和深度学习的音乐推荐系统正是为了解决这一问题而诞生。该系统通过深度学习技术分析用户的历史行为和偏好&#xff0…...

用普中开发板A234和Proteus 8.16,手把手复刻一个课堂/竞赛用的八路抢答器(附完整代码和避坑点)

用普中开发板A234和Proteus 8.16打造竞赛级八路抢答器实战指南 在电子设计竞赛、课堂互动或社团活动中&#xff0c;一个稳定可靠的抢答器往往是点燃现场气氛的关键设备。市面上虽然有不少成品抢答器&#xff0c;但价格昂贵且功能固定&#xff0c;难以满足个性化需求。而基于51单…...

百度百舸 x 昆仑芯,加速 GLM-5.1 从开源发布到规模化应用

今日&#xff0c;智谱正式开源新一代大模型 GLM 5.1。作为智谱 GLM 系列的最新力作&#xff0c;GLM-5.1 的整体能力得到了全面提升。尤其在代码能力上&#xff1a;在最接近真实软件开发的 SWE-bench Pro 基准测试中&#xff0c;GLM-5.1 超过 GPT-5.4、Claude Opus 4.6&#xff…...

Phi-4-mini-reasoning企业知识图谱增强:实体关系推理与逻辑补全案例

Phi-4-mini-reasoning企业知识图谱增强&#xff1a;实体关系推理与逻辑补全案例 1. 模型简介与核心能力 Phi-4-mini-reasoning 是一个基于合成数据构建的轻量级开源模型&#xff0c;专注于高质量、密集推理的数据处理能力。作为Phi-4模型家族的一员&#xff0c;它特别强化了数…...

OpenClaw+Qwen3.5-9B避坑指南:5个典型配置错误修复

OpenClawQwen3.5-9B避坑指南&#xff1a;5个典型配置错误修复 1. 为什么需要这份避坑指南 上周我在本地部署OpenClaw对接Qwen3.5-9B模型时&#xff0c;连续踩了三个配置坑&#xff0c;导致整个周末都在和报错信息搏斗。最崩溃的是&#xff0c;有些错误提示非常隐晦——比如模…...

新手也能搞定的应急响应实战:用知攻善防靶场复现近源渗透与挖矿事件

新手也能搞定的应急响应实战&#xff1a;用知攻善防靶场复现近源渗透与挖矿事件 网络安全应急响应是每个安全从业者的必修课&#xff0c;但对于刚入门的新手来说&#xff0c;面对真实的攻击事件往往无从下手。本文将带你通过知攻善防靶场&#xff0c;手把手复现"近源渗透O…...

为什么你的PHP 8.9异步服务仍卡在I/O?3个致命配置错误+2套生产环境验证方案

第一章&#xff1a;PHP 8.9异步I/O的核心演进与认知重构PHP 8.9并未真实发布——截至2024年&#xff0c;PHP官方最新稳定版本为PHP 8.3&#xff0c;PHP 8.4已进入RC阶段&#xff0c;而PHP 8.9尚属虚构版本。这一标题本质是一次思想实验&#xff1a;它邀请开发者跳出“等待发布”…...

别再肉眼找不同了!3步教你快速对比两个txt/word(即doc、docx)文档的差异

&#x1f680; 欢迎来到我的Office高效办公指南&#xff01;&#x1f4da; 亲爱的访客&#xff0c;你好呀&#xff01;&#x1f44b; 很高兴能在CSDN的海洋里与你相遇&#xff5e; ✨ 无论你是正在摸索Office的「职场萌新」 &#x1f4bc;&#xff0c;还是希望技能更上一层楼的…...

2026届最火的十大AI科研工具实际效果

Ai论文网站排名&#xff08;开题报告、文献综述、降aigc率、降重综合对比&#xff09; TOP1. 千笔AI TOP2. aipasspaper TOP3. 清北论文 TOP4. 豆包 TOP5. kimi TOP6. deepseek 为了把文本被判定成是由AI生成内容&#xff08;AIGC&#xff09;的可能性给降低下来&#xf…...

【计算机视觉】从Pixel到Mask:逐像素分类与掩码分类的实战对比

1. 计算机视觉中的像素级任务&#xff1a;从基础说起 第一次接触计算机视觉项目时&#xff0c;我盯着屏幕上密密麻麻的像素点发了好一会儿呆。这些看似简单的彩色小方块&#xff0c;究竟如何变成机器理解世界的语言&#xff1f;后来才明白&#xff0c;逐像素处理正是解锁图像理…...