CAS 底层 CPU 指令:cmpxchg¶
一、Java 层的 CAS¶
二、JVM 层¶
JVM 把它编译成 CPU 指令。x86 上是 lock cmpxchg:
语义¶
EAX 是默认寄存器,存期望值。
三、lock 前缀¶
lock 前缀保证:
1. 原子性:整个指令执行期间锁缓存行(MESI)。
2. 内存屏障:禁止重排。
3. 写回内存。
四、为什么 CAS 是原子的¶
cmpxchg本身是一条指令。lock前缀锁缓存行,其他核不能同时改。- 硬件保证读-比较-写一气呵成。
五、其他架构¶
- x86:
lock cmpxchg - ARM:
ldrex/strex(Load Exclusive / Store Exclusive) - RISC-V:
lr.d/sc.d
原理一样:独占加载 + 条件存储。
六、自旋¶
JVM 的 getAndAddInt 是 do-while 自旋:
CAS 失败说明被别的线程改了,重新读再试。
总结
CAS = CPU 一条原子指令 + Java 层自旋重试。不是"无锁",是"用户态无锁",底层还是硬件锁(缓存行锁)。