深入理解 volatile

volatile 到底做了什么?

太棒了!这个结构和深度已经非常好了。为了让它达到"教科书级"的清晰度,我主要在逻辑流畅性和视觉引导上做一次精炼优化。


一、问题根源:为什么需要 volatile?

案例1:永不停止的线程

arduino 复制代码
public class NeverStop {
    static boolean running = true;  // 危险:非 volatile
    
    public static void main(String[] args) throws InterruptedException {
        Thread worker = new Thread(() -> {
            while (running) { /* 空转 */ }  // 可能永远循环
        });
        worker.start();
        Thread.sleep(1000);
        running = false;  // 主线程修改,工作线程可能看不见
    }
}

📉 问题本质:缓存不一致


案例2:DCL单例的"半成品"对象

csharp 复制代码
instance = new Singleton();  // 实际分三步执行:
// 1. 分配内存空间
// 2. 初始化对象
// 3. 赋值引用

// 可能被重排序为:1 → 3 → 2

private static Singleton instance;

public static Singleton getInstance() {
    if (instance == null) {
        synchronized (Singleton.class) {
            if (instance == null) {
                instance = new Singleton(); // 可能重排序!
            }
        }
    }
    return instance;
}

📉 问题本质:指令重排序

ini 复制代码
线程A创建实例:
1. 分配内存
2. [重排序] instance = 地址  ← 引用提前发布!
3. 初始化对象

此时线程B检查:
if (instance != null)  → true
return instance;       → 拿到未初始化的对象!

二、volatile 的解决方案

解决方案1:强制可见性

arduino 复制代码
static volatile boolean running = true;

📈 执行流程对比图:

🔧 底层机制:

  • 写操作:强制刷新到主内存,并使其他CPU中该变量的缓存行失效
  • 读操作:强制从主内存重新加载最新值
  • 通信协议:基于CPU的MESI缓存一致性协议

解决方案2:禁止重排序

arduino 复制代码
private static volatile Singleton instance;

// new Singleton() 的执行顺序被固定:
// 1. 分配内存 → 2. 初始化 → 3. 赋值引用

🔧 底层机制:内存屏障

JVM在volatile操作前后插入内存屏障:

屏障类型 插入位置 作用
StoreStore volatile写之前 保证前面所有写操作先完成
StoreLoad volatile写之后 保证写操作对其他线程立即可见
LoadLoad volatile读之后 保证后面读操作不会重排到前面
LoadStore volatile读之后 保证后面写操作不会重排到前面
特性 普通变量 volatile变量
可见性 无保证 ✅ 强保证
原子性 无保证 ❌ 仍无保证(除long/double)
有序性 无保证 ✅ 禁止重排序
性能 最优 轻量级同步代价

💡 核心价值:volatile在可见性和有序性上提供轻量级保证,是介于"无同步"与"重量级锁"之间的优雅折中。

相关推荐
AskHarries1 小时前
Toolhub — 一个干净实用的在线工具集合
前端·后端
一个专注写bug的小白猿1 小时前
.net实现ftp传输文件保姆教程
后端·c#·.net
青皮桔2 小时前
Java+OpenCV实现图片切割
java·后端·opencv·计算机视觉
兮动人2 小时前
Spring中@Configuration注解的proxyBeanMethods属性详解
java·后端·spring
Jing_jing_X3 小时前
Spring 自动注入是怎么实现的?从 @Component 到 @Autowired 的完整流程
java·后端·spring
IT_陈寒3 小时前
5个Vue3性能优化技巧,让你的应用提速50% 🚀(附实测对比)
前端·人工智能·后端
00后程序员3 小时前
iOS 26 App 开发阶段性能优化 从多工具协作到数据驱动的实战体系
后端
PFinal社区_南丞3 小时前
从 trace 到洞察:Go 项目的可观测性闭环实践
后端
镜花水月linyi3 小时前
解锁AQS
java·后端·面试
少妇的美梦4 小时前
Kubernetes(K8s)YAML 配置文件编写教程
运维·后端