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

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 {
    // 对象类型CAS
    public final native boolean compareAndSwapObject(
        Object obj, long offset, Object expect, Object update);
    
    // int类型CAS
    public final native boolean compareAndSwapInt(
        Object obj, long offset, int expect, int update);
    
    // long类型CAS
    public 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性能优势明显

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

相关文章:

  • 【含文档+PPT+源码】基于微信小程序的乡村振兴民宿管理系统
  • c# sqlite 批量生成insert语句的函数
  • ubuntu基于docker部署呼叫中心质检【支持情绪,话术对比】
  • 计算机组成原理—— 总线系统(十一)
  • DeepSeek HuggingFace 70B Llama 版本 (DeepSeek-R1-Distill-Llama-70B)
  • 【MediaTek】 T750 openwrt-23.05编 cannot find dependency libexpat for libmesode
  • 对比 LVS 负载均衡群集的 NAT 模式和 DR 模式,比较其各自的优势 , 基于 openEuler 构建 LVS-DR 群集。
  • 【linux】文件与目录命令 - cut
  • 微信小程序地图标记点,安卓手机一次性渲染不出来的问题
  • node.js下载、安装、设置国内镜像源(永久)(Windows11)
  • 【愚公系列】《Python网络爬虫从入门到精通》008-正则表达式基础
  • 服务器延迟给视频网站造成的影响
  • RAG科普文!检索增强生成的技术全景解析
  • 基于SSM+uniapp的购药小程序+LW示例参考
  • 元学习之孪生网络Siamese Network
  • Whisper+T5-translate实现python实时语音翻译
  • 【MySQL】高频 SQL 50 题(基础版)
  • 每日一题——矩阵最长递增路径
  • 算法-哈希表03-快乐数
  • Django ORM:外键字段的命名与查询机制解析
  • 网站开发用什么语言好/优化网站标题名词解释
  • 做外贸一定要独立网站吗/如何联系百度客服
  • 行业网站产品选择/产品软文是什么
  • 珠海品牌网站建设/网站统计系统
  • 个人做网站需要备案吗/网页模板建站系统
  • 网站开发用什么系统/北京网站建设公司哪家好