cas的原子性由cpu硬件指令直接保证,如x86的cmpxchg指令将“读—比—写”封装为不可分割操作;通过mesi协议的缓存锁实现高效并发控制,java层仅通过unsafe调用该硬件能力。

CAS 的原子性不是 Java 或 JVM “做出来”的,而是直接由 CPU 硬件指令一条完成的。它不依赖软件逻辑、不靠锁排队、也不靠线程调度协调,靠的是 CPU 在硬件层面对“读—比—写”三步打包成不可分割的一个动作。
核心是 CPU 原语指令,比如 x86 的 cmpxchg
在 x86 架构上,CAS 对应的是 cmpxchg(Compare and Exchange)指令。它的执行过程是:
- CPU 把内存地址 V 中的当前值读进寄存器,和预期值 A 比较
- 如果相等,就把新值 B 写回 V;否则不写,只把 V 的最新值返回给寄存器
- 整个过程由 CPU 在一个不可中断的执行周期内完成,中间不会被调度、中断或其它核心干扰
硬件如何防止并发冲突?靠缓存锁,不是总线锁
现代 CPU 不再粗暴地锁住整条总线,而是利用 MESI 缓存一致性协议,在缓存行级别加锁:
- 当目标变量 V 所在的缓存行处于独占(M 状态)时,CPU 直接在本地缓存操作,用缓存锁保证原子性
- 只有在多个核心同时争抢同一缓存行时,才升级为更重的总线锁或跨核同步机制
- 这种设计大幅降低开销,让 CAS 在高并发下依然高效
Java 层只是调用桥梁,Unsafe 不实现原子性,只暴露原子性
sun.misc.Unsafe 类不是原子性的制造者,而是翻译官:
- 它的 compareAndSwapInt 等方法是 native 实现,最终触发的就是 cmpxchg 指令
- JVM 在底层 C++ 代码中插入内存屏障(Memory Barrier),确保 volatile 变量的可见性和指令重排约束
- AtomicInteger、ConcurrentHashMap 等类全部建立在这个硬件能力之上,不是靠 Java 代码拼出来的“原子”
CAS 失败时的行为也由硬件决定
cmpxchg 指令执行后,CPU 会设置标志位(如 ZF 零标志)并返回结果:
- 成功时 ZF=1,Java 层返回 true
- 失败时 ZF=0,且寄存器中已载入当前真实值,Java 层可据此决定是否自旋重试
- 多个线程同时 CAS 同一变量,硬件天然保证最多一个成功,其余全部失败,没有中间态
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











