volatile关键字如何防止指令重排序并强制变量刷新至主内存的硬件实现原理是什么?
- 内容介绍
- 相关推荐
本文共计1083个文字,预计阅读时间需要5分钟。
volatile关键字具有真正的威慑力,它不仅不保证让其他人看不到新值这个层面上的效果,而是在它用硬件级别的手柄同时处理了两件事:
内存屏障是 volatile 禁止重排序的执行载体
编译器和 CPU 都可能对指令做重排序,以提升性能。volatile 本身不直接“禁止”什么,它是在字节码层面告诉 JVM:“这个变量的读/写操作前后,必须插入特定类型的内存屏障”。JVM 进而生成带 LOCK 前缀 的汇编指令(如 lock xchg),由 CPU 硬件执行该指令时,自动触发内存屏障语义:
- volatile 写操作 后插入 StoreStore 屏障 + StoreLoad 屏障:确保该写之前的所有普通写已刷入缓存,且该写本身必须先于后续任意读/写执行;
- volatile 读操作 前插入 LoadLoad 屏障 + LoadStore 屏障:确保该读之前的所有普通读已完成,且该读的结果必须先于后续任意写生效。
这些屏障不是软件延时,而是 CPU 硬件流水线中的同步点——遇到屏障,当前核心会暂停部分乱序执行逻辑,等待屏障前的内存操作全局可见后,才放行屏障后的指令。
强制刷新主内存本质是缓存一致性协议的主动触发
所谓“刷新主内存”,准确说是让修改立即对其他 CPU 核心可见。
本文共计1083个文字,预计阅读时间需要5分钟。
volatile关键字具有真正的威慑力,它不仅不保证让其他人看不到新值这个层面上的效果,而是在它用硬件级别的手柄同时处理了两件事:
内存屏障是 volatile 禁止重排序的执行载体
编译器和 CPU 都可能对指令做重排序,以提升性能。volatile 本身不直接“禁止”什么,它是在字节码层面告诉 JVM:“这个变量的读/写操作前后,必须插入特定类型的内存屏障”。JVM 进而生成带 LOCK 前缀 的汇编指令(如 lock xchg),由 CPU 硬件执行该指令时,自动触发内存屏障语义:
- volatile 写操作 后插入 StoreStore 屏障 + StoreLoad 屏障:确保该写之前的所有普通写已刷入缓存,且该写本身必须先于后续任意读/写执行;
- volatile 读操作 前插入 LoadLoad 屏障 + LoadStore 屏障:确保该读之前的所有普通读已完成,且该读的结果必须先于后续任意写生效。
这些屏障不是软件延时,而是 CPU 硬件流水线中的同步点——遇到屏障,当前核心会暂停部分乱序执行逻辑,等待屏障前的内存操作全局可见后,才放行屏障后的指令。
强制刷新主内存本质是缓存一致性协议的主动触发
所谓“刷新主内存”,准确说是让修改立即对其他 CPU 核心可见。

