Java并发中的CAS机制:原理、应用与挑战(通俗易懂版)

上一期文章内容:Java并发中的乐观锁与悲观锁,

本期文章我们来讲一下Java并发中的CAS机制


一、从银行账户案例理解CAS

        CAS 是一种乐观锁机制,用于在不使用锁的情况下实现多线程对共享资源的并发访问

        它包含三个操作数:内存位置(V)、预期原值(A)和新值(B)。

        当且仅当内存位置 V 的值等于预期原值 A 时,才将内存位置 V 的值更新为新值 B;

        否则,不做任何操作。整个 CAS 操作是原子性的,由 CPU 硬件指令直接支持。

        想象这样一个场景:你和朋友同时查看一个银行账户余额为100元,你们都尝试转账。传统做法是银行用"锁"机制,只允许一人操作。而CAS(Compare-And-Swap比较交换)采用更聪明的策略:

  1. 你查询当前余额:100元(旧值)

  2. 系统记录此刻的版本号为V1

  3. 当你提交转账时,系统会检查:

    • 当前余额是否仍是100元?

    • 版本号是否还是V1?

  4. 只有当两者都满足时,转账才会成功,并更新版本号为V2

这种无锁机制就像超市自助结账——不需要收银员(锁),顾客(线程)自己完成操作,系统通过版本检查保证安全。


二、Java底层实现揭秘

2.1 神秘的Unsafe类

Java通过sun.misc.Unsafe类实现CAS,这个类就像Java世界的"瑞士军刀",为什么会这么说呢?

因为 sun.misc.Unsafe 类功能强大并且多样,提供了直接操作内存、基于CAS的操作方法、线程调度相关方法等的能力,但是我们在使用时需要持谨慎态度,因为会涉及安全、可移植、代码维护等问题!

public final class Unsafe {// 对象类型CASpublic final native boolean compareAndSwapObject(Object obj, long offset, Object expect, Object update);// int类型CASpublic final native boolean compareAndSwapInt(Object obj, long offset, int expect, int update);// long类型CASpublic final native boolean compareAndSwapLong(Object obj, long offset, long expect, long update);
}

通过JNI调用本地代码,最终映射到CPU指令(如x86的CMPXCHG),整个过程就像:

  1. 获取当前值

  2. 计算新值

  3. 调用CPU指令进行原子比较交换

2.2 AtomicInteger实现解析

AtomicInteger为例,看Java如何包装CAS:

public class AtomicInteger {private volatile int value; // 保证可见性private static final Unsafe unsafe = Unsafe.getUnsafe();private static final long valueOffset; // 内存偏移量static {try {valueOffset = unsafe.objectFieldOffset(AtomicInteger.class.getDeclaredField("value"));} catch (Exception ex) { throw new Error(ex); }}public final boolean compareAndSet(int expect, int update) {return unsafe.compareAndSwapInt(this, valueOffset, expect, update);}
}

关键点说明:

  • volatile保证值变更的可见性

  • 内存偏移量定位字段位置

  • CAS失败时自动重试(自旋

三、CAS的三大挑战与应对

3.1 ABA问题:账户余额的"时空穿越"

假设账户余额变化:100 → 200 → 100

  1. 线程A读取100(版本V1)

  2. 线程B完成两次修改(V1→V2→V3)

  3. 线程A的CAS检查值仍是100,但版本已变化

解决方案: 使用带版本号的AtomicStampedReference

AtomicStampedReference<Integer> account = new AtomicStampedReference<>(100, 0);// 存款操作
int[] stampHolder = new int[1];
int current = account.get(stampHolder);
if(account.compareAndSet(current, current+50, stampHolder[0], stampHolder[0]+1)) {System.out.println("存款成功");
}

3.2 自旋开销:CPU的"空转危机"

当多个线程激烈竞争时,CAS可能导致CPU空转。优化策略:

  1. 自适应自旋:JVM动态调整自旋次数

  2. pause指令:插入CPU提示指令降低功耗

    // x86架构实现示例
    __asm__ volatile ("pause");
  3. 退避策略:随机等待后再重试

3.3 多变量原子性:关联操作的困局

需要保证多个变量的原子更新时:

方案一:对象包装

class Account {int balance;int version;
}AtomicReference<Account> atomicAccount = new AtomicReference<>();

方案二:锁机制

synchronized(lock) {account.balance -= amount;account.version++;
}

四、CAS应用场景分析

场景适用性示例
计数器★★★★★AtomicInteger
状态标志★★★★★AtomicBoolean
对象引用更新★★★★☆AtomicReference
复杂数据结构★★☆☆☆ConcurrentHashMap内部实现
事务性操作★☆☆☆☆需要结合其他机制

五、性能对比:CAS vs 锁
 

通过JMH基准测试(ops/ms):

线程数    CAS    同步锁      ReentrantLock
1  15234    14567        14230
4  12345    2345        4566
8  9876    1023        2348

结论:

        低竞争场景:性能相近

        高并发场景:CAS性能优势明显

        极端竞争:可能需要退化为锁机制

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

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

相关文章

SpringBoot自动配置-以Mybatis配置为例

SpringBoot自动配置 无基础的直接看链接内容&#xff0c;有基础就直接顺着往下看就可以 Spring底层&#xff08;自动配置&#xff09; 自动配置就是EnableXXX封装Improt&#xff08;ImportSelector的实现类&#xff09;对应方法selectImoprt返回字符串数组为类名会注册为bean…

2025 docker可视化管理面板DPanel的安装

1.什么是 DPanel &#xff1f; DPanel 是一款 Docker 可视化管理面板&#xff0c;旨在简化 Docker 容器、镜像和文件的管理。它提供了一系列功能&#xff0c;使用户能够更轻松地管理和部署 Docker 环境。 软件特点&#xff1a; 可视化管理&#xff1a;提供直观的用户界面&#…

DeepSeek从入门到精通(清华大学)

​ DeepSeek是一款融合自然语言处理与深度学习技术的全能型AI助手&#xff0c;具备知识问答、数据分析、编程辅助、创意生成等多项核心能力。作为多模态智能系统&#xff0c;它不仅支持文本交互&#xff0c;还可处理文件、图像、代码等多种格式输入&#xff0c;其知识库更新至2…

Word 里面嵌入DeepSeek

目录 一、问题描述 二、解决方法 三、代码 四、注意事项 五、总结 一、问题描述 如何在Word里面嵌入DeepSeek? 二、解决方法 1、新建文档&#xff0c;按 AltF11&#xff0c;进入VB界面。 2、选中文档&#xff0c;右键->插入->模块。 3、进入模块&#xff0c;粘入…

java面试题-集合篇

Collection 1.Collection有哪些类&#xff1f; Java集合框架中的Collection接口是所有集合类的基础接口&#xff0c;定义了一些基本的集合操作&#xff0c;如添加元素、删除元素、判断是否包含某个元素等。常见的集合类包括List、Set和Queue。 List List接口定义了按照索引…

国内 网络安全沙箱

CSRF攻击 CSRF攻击概述&#xff1a; CSRF&#xff08;Cross Site Request Forgery, 跨站域请求伪造&#xff09;是一种网络的攻击方式&#xff0c;它在 2007 年曾被列为互联网 20 大安全隐患之一。其他安全隐患&#xff0c;比如 SQL 脚本注入&#xff0c;跨站域脚本攻击等在近…

Web3 的虚实融合之路:从虚拟交互到元宇宙构建

在这个数字技术日新月异的时代&#xff0c;我们正站在 Web3 的门槛上&#xff0c;见证着互联网的又一次革命。Web3 不仅仅是技术的迭代&#xff0c;它代表了一种全新的交互方式和价值创造模式。本文将探讨 Web3 如何推动虚拟交互的发展&#xff0c;并最终实现元宇宙的构建&…

项目中菜单按照层级展示sql

效果如图&#xff1a; 直接上脚本 查四级菜单 select EFT_FLAG,MENU_ID, CASE LEN(MENU_LVL)WHEN 4THEN MENU_NAME ELSE - END AS MENU_NAME1, CASE LEN(MENU_LVL)WHEN 8THEN MENU_NAME ELSE - END AS MENU_NAME2, CASE LEN(MENU_LVL)WHEN 12THEN MENU_NAME ELSE - END …

Reasoning in High Gear 推理加速发展

Reasoning in High Gear 推理加速发展 关键信息&#xff1a;OpenAI推出GPT - 3 - mini&#xff0c;它是GPT - 1模型后续版本&#xff0c;在速度、成本及特定领域能力上有显著优势。 模型特性 推理强度可选&#xff1a;提供低、中、高三个推理 “强度” 级别&#xff0c;不同级别…

Linux驱动层学习:LED 驱动开发

前置知识&#xff1a; 1、地址映射 MMU 全称叫做 Memory Manage Unit&#xff0c;也就是内存管理单元。 MMU 主要完成的功能如下&#xff1a; ①、完成虚拟空间到物理空间的映射。 ②、内存保护&#xff0c;设置存储器的访问权限&#xff0c;设置虚拟存储空间的缓冲特性。 第…

数据挖掘智能Agent

&#x1f917; CodeGenie - 智能编程助手 数据处理和分析对于数据分析工作人员来说&#xff0c;往往既复杂又令人头疼&#xff0c;需要耗费大量精力进行重复性工作。为了解决这一问题&#xff0c;我们开发了一款集成了自然语言处理和代码生成功能的智能编程助手——CodeGenie。…

【C++】Vector容器

为什么要学习vector&#xff1f; 1. 上一章分享了string&#xff0c;而string实际上是一个管理字符的顺序表。 2. 而除了字符以外&#xff0c;我们经常用到整形数组&#xff0c;所以我们需要针对其他类型数据的顺序表。 3. vector实际上也是一个顺序表&#xff0c;而且主要用来…

国内 ChatGPT Plus/Pro 订阅教程

1. 登录 chat.openai.com 依次点击 Login &#xff0c;输入邮箱和密码 2. 点击升级 Upgrade 登录自己的 OpenAI 帐户后&#xff0c;点击左下角的 Upgrade to Plus&#xff0c;在弹窗中选择 Upgrade plan。 如果升级入口无法点击&#xff0c;那就访问这个网址&#xff0c;htt…

Winform禁止高分辨下缩放布局成功方法

Windows自动缩放布局会导致窗体上的按钮和文本挤在一起根本看不清楚。 那么该如何解决呢&#xff1f; 具体操作步骤如下&#xff1a; 1、在项目属性上切换到【安全性】菜单&#xff0c;勾选【启用ClickOnce安全设置】&#xff0c;然后立刻取消勾选&#xff1b; 为了生成app.…

数据结构——Makefile、算法、排序(2025.2.13)

目录 一、Makefile 1.功能 2.基本语法和相关操作 &#xff08;1&#xff09;创建Makefile文件 &#xff08;2&#xff09;编译规则 &#xff08;3&#xff09;编译 &#xff08;4&#xff09;变量 ①系统变量 ②自定义变量 二、 算法 1.定义 2.算法的设计 &#xff…

Xcode证书密钥导入

证书干嘛用 渠道定期会给xcode证书&#xff0c;用来给ios打包用&#xff0c;证书里面有记录哪些设备可以打包进去。 怎么换证书 先更新密钥 在钥匙串访问中&#xff0c;选择系统。(选登录也行&#xff0c;反正两个都要导入就是了)。 mac中双击所有 .p12 后缀的密钥&#xff…

span标签 鼠标移入提示框 el-tooltip element-ui

<el-tooltip :content"item.value" placement"top"><span>{{ item.valueHidden }}</span></el-tooltip>

[创业之路-300]:进一步理解货币与金钱, 货币与货币政策

目录 一、货币 1.1 概述 1、货币的定义 2、货币的形态演变 3、货币的职能 4、货币的价值衡量 1.2 货币的分层 1、货币分层的目的与意义 2、货币分层的划分标准与层次 3、各国货币分层的实践 4、货币分层的影响与应用 1.3、M0、M1、M2变化对股市的影响 1、M0变化对…

pnpm的使用

pnpm的使用 1.安装和使用2.统一包管理工具下载依赖 1.安装和使用 pnpm:performant npm &#xff0c;意味“高性能的npm”。 pnpm由npm/yarn衍生而来,解决了npm/yarn内部潜在的bug,极大的优化了性能,扩展了使用场景。被誉为“最先进的包管理工具”。 pnpm安装指令: npm i -g p…

vue+springboot+webtrc+websocket实现双人音视频通话会议

前言 最近一些时间我有研究&#xff0c;如何实现一个视频会议功能&#xff0c;但是找了好多资料都不太理想&#xff0c;最终参考了一个文章 WebRTC实现双端音视频聊天&#xff08;Vue3 SpringBoot&#xff09; 只不过&#xff0c;它的实现效果里面只会播放本地的mp4视频文件&…