CAS(Compare And Swap)

CAS核心原理

操作流程

CAS 包含三个参数:内存值(V)预期值(E)和新值(N)。执行步骤如下:

  • 比较:检查当前内存值 V 是否等于预期值 E。

  • 交换:如果相等,将内存值更新为新值 N;否则不操作。

  • 返回结果:返回操作是否成功(或当前实际值)。整个过程是原子性的,由 CPU 指令直接保证,例如 Intel 的 cmpxchg 指令。

    AtomicInteger atomicInt = new AtomicInteger(5);
    boolean success = atomicInt.compareAndSet(5, 10); // 若当前值为5,则更新为10
    //若 atomicInt 的当前值未被其他线程修改,则更新成功(返回 true),否则失败(返回false)
    

原子性保障

CPU 通过两种机制保证 CAS 的原子性:

总线锁定

  • 使用 LOCK# 信号锁定总线,阻止其他 CPU 访问内存,确保当前操作独占执行。
  • 缺点:锁定期间其他 CPU 无法操作内存,性能开销大

缓存锁定

  • 仅锁定缓存行(CPU 高速缓存的最小单位),通过 缓存一致性协议(如 MESI)检测共享变量是否被修改。
  • 优势:缩小锁定范围,减少阻塞,现代 CPU 普遍采用此方式。

应用场景

原子类Atomic

//Java 的 AtomicInteger、AtomicReference 等类通过 CAS 实现线程安全的原子操作。
public final int incrementAndGet() {for (;;) {int current = get();           // 当前值int next = current + 1;        // 新值if (compareAndSet(current, next)) return next;               // 更新成功则返回}
}
//自旋循环中不断尝试 CAS,直到成功。

并发容器

  • ConcurrentHashMap:初始化数组时通过 sizeCtl 变量和 CAS 确保只有一个线程执行初始化,其他线程自旋等待或调用 Thread.yield() 让出 CPU
  • ConcurrentLinkedQueue:无锁队列通过 CAS 实现入队和出队的线程安全

自旋锁和无锁算法

//自旋锁:线程通过循环尝试 CAS 获取锁,避免阻塞和上下文切换。例如:
while (!lock.compareAndSet(0, 1)) { /* 自旋 */ }
//非阻塞数据结构:如无锁栈、队列等,依赖 CAS 实现并发安全

优缺点

在这里插入图片描述

ABA问题和解决方案

问题描述

  • 线程 1 读取值 A,线程 2 将 A→B→A,线程 1 的 CAS 仍会成功,导致逻辑错误(例如链表头节点被意外删除)

解决方案

//版本号机制:每次更新递增版本号,检查值的同时检查版本号。
//AtomicStampedReference:Java 提供带版本号的原子类。
AtomicStampedReference<Integer> ref = new AtomicStampedReference<>(100, 1);
ref.compareAndSet(100, 200, 1, 2); // 版本号从1→2
```[2](@ref) [4](@ref)

java中的cas实现

  1. Unsafe类:CAS 操作通过 Unsafe 类调用本地方法(如 compareAndSwapInt),直接操作内存地址
  2. 底层指令映射:JVM 将 compareAndSet 映射为 CPU 的 cmpxchg 指令,确保原子性

总结

  • CAS 是一种高效的无锁并发控制机制,适用于计数器、轻量级锁等场景。其核心优势是避免线程阻塞,但需注意 ABA 问题和自旋开销。在高并发系统中,CAS 常与退让策略(指数退避)(如 Thread.yield())结合,平衡性能与资源消耗
    • 指数退避:指数退避是一种动态调整重试延迟时间的算法,旨在通过指数级增长的等待时间和随机抖动减少系统资源竞争或网络冲突,提升系统的稳定性和效率。其核心思想是:在每次尝试失败后,延迟时间成倍增加,从而避免因频繁重试导致的资源过载或冲突加剧。
    • 核心原理:延迟时间指数增长、随机抖动、最大延迟限制
      • 延迟时间指数增长:初始设定一个最小延迟(如 100ms),每次失败后延迟时间按指数倍数(如 2 倍)增长。例如:第 1 次重试延迟 100ms,第 2 次 200ms,第 3 次 400ms,依此类推。
      • 随机抖动(Jitter):在延迟时间中加入随机值(如 0~100ms),防止多个请求在同一时间点集中重试,避免“雪崩效应”
        200ms,第 3 次 400ms,依此类推。
      • 随机抖动(Jitter):在延迟时间中加入随机值(如 0~100ms),防止多个请求在同一时间点集中重试,避免“雪崩效应”
      • 最大延迟限制:设置上限(如 30 秒),防止无限等待

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

宝塔面板安装docker flarum失败,请先安装依赖应用: [‘mysql‘]:5/8

安装失败的解决方案 提示错误请先安装依赖应用: [mysql]:5/8 解决方案&#xff1a;不要使用最新的docker mysql&#xff0c;使用5.7.44版本docker mysql&#xff0c;等安装完毕再安装docker flarum就不会报错了。 如果安装完成你不知道默认的账号密码可以看这里 宝塔docker f…

c#的.Net Framework 的console 项目找不到System.Window.Forms 引用

首先确保是建立的.Net Framework 的console 项目,然后天健reference 应用找不到System.Windows.Forms 引用 打开对应的csproj 文件 在第一个PropertyGroup下添加 <UseWindowsForms>true</UseWindowsForms> 然后在第一个ItemGroup 下添加 <Reference Incl…

基于 mxgraph 实现流程图

mxgraph 可以实现复杂的流程图绘制。mxGraph里的Graph指的是图论(Graph Theory)里的图而不是柱状图、饼图和甘特图等图(chart)&#xff0c;因此想找这些图的读者可以结束阅读了。 作为图论的图&#xff0c;它包含点和边&#xff0c;如下图所示。 交通图 横道图 架构图 mxGrap…

21.Excel自动化:如何使用 xlwings 进行编程

一 将Excel用作数据查看器 使用 xlwings 中的 view 函数。 1.导包 import datetime as dt import xlwings as xw import pandas as pd import numpy as np 2.view 函数 创建一个基于伪随机数的DataFrame&#xff0c;它有足够多的行&#xff0c;使得只有首尾几行会被显示。 df …

STL之空间配置器

1. 什么是空间配置器 空间配置器&#xff0c;顾名思义就是为各个容器高效的管理空间(空间的申请与回收)的&#xff0c;在默默地工作。虽然在常规使用STL时&#xff0c;可能用不到它&#xff0c;但站在学习研究的角度&#xff0c;学习它的实现原理对我们有很大的帮助。 2. 为什…

Axure项目实战:智慧城市APP(三)教育查询(显示与隐藏交互)

亲爱的小伙伴&#xff0c;在您浏览之前&#xff0c;烦请关注一下&#xff0c;在此深表感谢&#xff01; 课程主题&#xff1a;教育查询 主要内容&#xff1a;教育公告信息&#xff0c;小升初、初升高、高考成绩查询&#xff1b;教育公告信息为传统的信息页面&#xff0c;小升…

最大字段和问题 C++(穷举、分治法、动态规划)

问题描述 给定由n个整数&#xff08;包含负整数&#xff09;组成的序列a1,a2,…,an&#xff0c;求该序列子段和的最大值。规定当所有整数均为负值时定义其最大子段和为0 穷举法 最简单的方法就是穷举法&#xff0c;用一个变量指示求和的开始位置&#xff0c;一个变量指示结束…

【数据转换】- Halcon<->Mat

背景介绍 最近在写C#联合Haclon调用C的.dll文件进行联合编程。大致需求就是C#设计界面&#xff0c;然后调用Haclon的图像处理库&#xff0c;C把目标检测的模型进行TensorRT部署生成动态链接库&#xff0c;之后界面操作加载模型、对图像进行检测等功能。 设计界面如下&#xf…

MFC中如何判断一个窗口当前状态是显示还是隐藏

文章目录 一、核心方法&#xff1a;使用 CWnd::IsWindowVisible函数原型示例代码 二、注意事项1. 父窗口的影响2. 窗口最小化/最大化状态3. 窗口尚未创建 三、扩展&#xff1a;通过窗口样式直接判断四、完整示例代码五、总结 在MFC中&#xff0c;判断窗口当前是显示还是隐藏状态…

Java 大视界 -- 基于 Java 的大数据分布式系统的监控与运维实践(155)

&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎来到 青云交的博客&#xff01;能与诸位在此相逢&#xff0c;我倍感荣幸。在这飞速更迭的时代&#xff0c;我们都渴望一方心灵净土&#xff0c;而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识&#xff0c;也…

消息队列性能比拼: Kafka vs RabbitMQ

本内容是对知名性能评测博主 Anton Putra Kafka vs RabbitMQ Performance 内容的翻译与整理, 有适当删减, 相关数据和结论以原作结论为准。 简介 在本视频中&#xff0c;我们将首先比较 Apache Kafka 和传统的 RabbitMQ。然后&#xff0c;在第二轮测试中&#xff0c;会将 Kaf…

[ComfyUI] SDXL Prompt Styler 自定义节点的作用解析

1. SDXL Prompt Styler 的位置与基本功能 在 ComfyUI 的 “新建节点” → “实用工具” 下,可以找到 Style 节点(SDXL Prompt Styler)。该节点的主要作用是对输入的描述进行结构化处理,并在转换为 Stable Diffusion XL (SDXL) 提示词时,自动补充风格相关的内容,使提示词…

【JavaScript】金丹期功法

目录 数组声明数组数组的基本使用遍历数组案例&#xff1a;求数组中的最值数组操作查询数据修改数据新增数据案例&#xff1a;数组筛选删除数据 案例&#xff1a;渲染柱形图 数组 数组&#xff08;Array&#xff09;是一种可以按顺序保存数据的数据类型 场景&#xff1a;如果…

学习本地部署DeepSeek的过程(基于LM Studio)

除了使用Ollama部署DeepSeek&#xff0c;还可以使用LM Studio部署DeepSeek&#xff0c;后者是一款允许用户在本地计算机上运行大型语言模型&#xff08;LLMs&#xff09;的桌面应用程序&#xff0c;旨在简化本地模型的使用&#xff0c;无需云端连接或复杂配置即可体验 AI 功能。…

AOA与TOA混合定位,MATLAB例程,自适应基站数量,三维空间下的运动轨迹,滤波使用EKF

本代码实现了一个基于 到达角(AOA) 和 到达时间(TOA) 的混合定位算法,结合 扩展卡尔曼滤波(EKF) 对三维运动目标的轨迹进行滤波优化。代码通过模拟动态目标与基站网络,展示了从信号测量、定位解算到轨迹滤波的全流程,适用于城市峡谷、室内等复杂环境下的定位研究。 文…

C++:函数(通识版)

一、函数的基础 1.什么是函数&#xff1f;&#xff08;独立的功能单位&#xff09; 函数是C中封装代码逻辑的基本单元&#xff0c;用于执行特定任务。 作用&#xff1a;代码复用、模块化、提高可读性。 2、函数的基本结构 返回类型 函数名(参数列表) {// 函数体return 返回值…

STL之map和set

1. 关联式容器 vector、list、deque、 forward_list(C11)等&#xff0c;这些容器统称为序列式容器&#xff0c;因为其底层为线性序列的数据结构&#xff0c;里面存储的是元素本身。 关联式容器也是用来存储数据的&#xff0c;与序列式容器不同的是&#xff0c;其里面存储的是结…

虚拟机(一):Java 篇

虚拟机&#xff08;一&#xff09;&#xff1a;Java 篇 虚拟机&#xff08;二&#xff09;&#xff1a;Android 篇 架构 运行时数据区&#xff1a; 栈&#xff1a; 堆&#xff1a; 堆&#xff1a;通过new创建的对象都在堆中分配。OutOfMemoryError TLAB(Thread Local All…

无线安灯按钮盒汽车零部件工厂的故障告警与人员调度专家

在汽车零部件制造领域&#xff0c;生产线故障与物料短缺等问题往往引发连锁反应&#xff0c;导致停机损失与成本激增。传统人工巡检与纸质工单模式已难以满足高效生产需求&#xff0c;而无线安灯按钮盒的智能化应用&#xff0c;正成为破解这一难题的关键利器。 一、精准告警&am…

二叉树相关算法实现:判断子树与单值二叉树

目录 一、判断一棵树是否为另一棵树的子树 &#xff08;一&#xff09;核心思路 &#xff08;二&#xff09;代码实现 &#xff08;三&#xff09;注意要点 二、判断一棵树是否为单值二叉树 &#xff08;一&#xff09;核心思路 &#xff08;二&#xff09;代码实现…