惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Last Week in AI
Last Week in AI
阮一峰的网络日志
阮一峰的网络日志
P
Proofpoint News Feed
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
MongoDB | Blog
MongoDB | Blog
云风的 BLOG
云风的 BLOG
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
J
Java Code Geeks
WordPress大学
WordPress大学
T
The Blog of Author Tim Ferriss
V
Visual Studio Blog
小众软件
小众软件
Microsoft Azure Blog
Microsoft Azure Blog
博客园_首页
IT之家
IT之家
Vercel News
Vercel News
C
Check Point Blog
Google DeepMind News
Google DeepMind News
月光博客
月光博客
D
DataBreaches.Net
酷 壳 – CoolShell
酷 壳 – CoolShell
美团技术团队
Y
Y Combinator Blog
Hugging Face - Blog
Hugging Face - Blog

Liu Zijian's Blog | 一个技术博客

使用Certbot自动续签HTTPS证书 使用Filebeat采集Nginx日志到ES Python的协程 Python中的异常 Python中的类和对象 Python的函数 Python的数据结构,推导式、迭代器和生成器 Spring AI集成多模态模型 LangChain4j多模态 LangChain Tools工具使用 Python中的模块和包 Python全局环境和虚拟环境(venv) LangChain Prompt提示词工程 LangChain4j Tools工具使用 基于Dify搭建AI智能体应用 LangChain4j RAG检索增强生成 Spring AI实现MCP Server Spring AI集成MCP Client LangChain4j Prompt提示词工程 Spring AI使用知识库增强对话功能 Spring AI实现一个智能客服 Spring AI实现一个简单的对话机器人 实现MinIO数据的每日备份 自己实现一个DNS服务 简单理解AI智能体 大模型和大模型应用 LangChain开篇 LangChain4j开篇 一个解析Excel2007的POI工具类 DataPermissionInterceptor源码解读
volatile作用分析
Liu Zijian · 2022-05-01 · via Liu Zijian's Blog | 一个技术博客

Java 内存模型 (JMM) 中的一个核心问题是线程对共享变量的可见性。在多线程环境中,每个线程都有自己的工作内存(即 CPU 缓存)。当一个线程修改了某个变量,其他线程并不能立即看到这个修改,因为每个线程可能都在使用自己工作内存中的缓存值。

volatile 的可见性机制:

  • 强制刷新主内存:当一个线程对 volatile 修饰的变量进行写操作时,修改后的值会立即被刷新到主内存中,而不是缓存在该线程的工作内存中。

  • 强制读取主内存:当一个线程对 volatile 修饰的变量进行读操作时,会直接从主内存中读取最新值,而不会从线程的工作内存中读取缓存的值。

  • 示例代码

public class TestVolatile {
    
    static volatile boolean flag = false;
    
    public static void main(String[] args) {
        
        new Thread(() -> {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            flag = true;
            
            System.out.println("子线程修改flag的值为:  " + flag);
            
        }).start();
        
        
        // while(true) 调用底层代码,效率极高,不会从主存中再次获取被其他线程修改过的数据
        while (true) {
            if (flag) {
                System.out.println("flag is true 主线程结束循环!");
                break;
            }

        }

    }
}

因此,volatile 保证了变量的可见性,即当一个线程修改了 volatile 变量后,其他线程能够立即看到最新的值。

volatile 与 synchronized 的对比

特性 volatile synchronized
可见性 保证可见性 保证可见性
原子性 不保证原子性 保证原子性
重排序 禁止指令重排序 保证顺序执行
性能开销 较低(无锁机制) 较高(加锁/解锁开销)
使用场景 适用于简单状态标志位或单次读写 适用于复杂的临界区保护