cas底层靠cpu原子指令(如x86的lock cmpxchg)触发mesi协议动态保障一致性,以缓存行为单位协同更新状态,失败时自然重试,无需软件维护状态。

CAS 底层不靠“主动维护”变量状态,而是靠硬件协议在操作发生时动态保证一致性。Java 里的 compareAndSet 调用最终会触发 CPU 的原子指令(如 x86 上的 lock cmpxchg),这个过程本身就会驱动缓存一致性协议(如 MESI)介入,确保多核看到的值始终是最新且互斥的。
缓存行是同步的基本单位
CPU 不按字节、也不按变量,而是按缓存行(通常 64 字节)来管理数据。只要两个变量落在同一缓存行里,哪怕逻辑上无关,一个被修改也会导致另一变量所在核心的缓存失效——这就是“伪共享”的根源。CAS 操作的目标地址一旦被访问,整个缓存行就进入 MESI 协议的跟踪范围。
- 当某个核心执行 CAS 时,先检查目标缓存行状态:如果是 Exclusive 或 Modified,可直接本地完成读-比-写;
- 如果是 Shared,该核心会发起 RFO(Request For Ownership)请求,其他核心收到后把对应缓存行置为 Invalid;
- 只有获得独占权的核心才能成功写入新值,失败的核心则收到 false 并重试。
指令自动触发协议协同,无需软件干预
lock cmpxchg 这条指令本身不显式“加锁”,但它的执行会隐式要求硬件保证原子性。现代 CPU 在执行时自动完成三件事:
- 阻塞其他核心对该缓存行的读写(不是整条总线);
- 通过嗅探(snooping)监听总线/互连上的 RFO 和 invalidate 请求;
- 根据 MESI 状态机更新本地缓存行,并广播状态变更。
这个过程对 JVM 和 Java 程序完全透明——开发者调用 AtomicInteger.compareAndSet,JVM 编译成带 lock 前缀的指令,CPU 微架构负责落地执行和协议协调。
可见性由协议刷新而非“推送”保障
CAS 成功后,新值不会立刻“推”给其他核心。它依赖缓存一致性协议的被动响应机制:
- 写入方把新值存入本地缓存,并标记为 Modified;
- 后续其他核心若要读该地址,发现缓存行是 Invalid,就会重新从内存或拥有 Modified 状态的核心拉取最新值;
- volatile 语义与 CAS 天然兼容:因为
lock cmpxchg具有 full memory barrier 效果,能刷出 Store Buffer,让写操作对其他核可见。
失败重试是协议结果的自然体现
两个核心同时对同一变量 CAS,不可能都成功——这不是靠“谁先抢到锁”,而是硬件串行化执行的结果。MESI 协议确保任意时刻最多一个核心处于 Exclusive 或 Modified 状态。后到达的核心在尝试获取所有权时被阻塞或拒绝,CAS 返回 false,程序逻辑决定是否重试。这种“乐观+重试”模式,正是建立在缓存一致性协议稳定、可预期的行为之上。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











