0

0

在Java中volatile如何保证可见性_Java volatile内存语义解析

P粉602998670

P粉602998670

发布时间:2025-12-19 16:12:07

|

613人浏览过

|

来源于php中文网

原创

volatile保证可见性靠内存屏障、禁止重排序和强制刷新缓存协同实现,写操作立即刷回主内存并使其他缓存失效,读操作强制从主内存加载最新值,但不保证复合操作原子性。

在java中volatile如何保证可见性_java volatile内存语义解析

volatile 保证可见性的核心,不是靠锁或阻塞,而是通过内存屏障(Memory Barrier)+ 禁止指令重排序 + 强制刷新缓存三者协同实现的。

volatile写操作:立即刷回主内存

当一个线程对volatile变量执行写操作时,JVM会插入一个StoreStore屏障(写-写屏障),确保该写操作之前的所有普通写操作都已提交到主内存;紧接着插入一个StoreLoad屏障,强制将当前线程工作内存中该volatile变量的最新值立即写入主内存,并使其他CPU缓存中该变量的副本失效。

  • 不是“慢慢同步”,而是“写完立刻可见”
  • 不保证原子性(如i++仍需synchronized或AtomicInteger)
  • 底层常对应x86的lock xaddmfence指令

volatile读操作:强制从主内存加载

当一个线程读取volatile变量时,JVM会插入一个LoadLoad屏障(读-读屏障),再插入一个LoadStore屏障,确保该读操作之后的普通读/写不会被重排到它前面;更重要的是,它禁止使用寄存器或本地缓存中的旧值,必须从主内存(或通过MESI协议获取最新值)重新读取。

  • 每次读都是“新鲜”的,不会命中过期缓存
  • 读操作本身不加锁,开销远小于synchronized
  • 配合写操作,构成“一个线程写 → 主内存更新 → 其他线程读 → 强制拉新”的可见链

volatile为什么不能保证原子性?

可见性 ≠ 原子性。比如volatile int count = 0;,执行count++实际分三步:读count、加1、写回count。虽然每一步的读和写都可见,但中间可能被其他线程打断——两个线程同时读到0,各自加1后都写回1,结果丢失一次更新。

XAnswer
XAnswer

XAnswer是一款可以生成思维导图的AI搜索工具,聚合全网优质信息源,结合LLM能力和RAG技术, 为用户提供实时性的搜索结果、个性化的答案呈现。

下载

立即学习Java免费学习笔记(深入)”;

  • volatile只保证单个读或单个写的原子性(Java内存模型规定long/double非volatile时可能有半个字问题,volatile可避免)
  • 复合操作(read-modify-write)天然非原子,需用synchronized、Lock或java.util.concurrent.atomic包

volatile的典型适用场景

适合状态标志、一次性安全发布、双重检查锁中的实例引用等无需复合操作、仅需状态通知的场合。

  • 线程控制开关:volatile boolean running = true;,另一线程设为false后,原线程能立即看到
  • 单例模式中防止指令重排序:volatile Singleton instance;,避免new对象过程被重排导致其他线程拿到未初始化完成的对象
  • 不适用于count++、list.add()等需要读-改-写语义的操作

基本上就这些。volatile的可见性是JMM在硬件层与编译器层共同保障的结果,理解它关键在于抓住“写即刷出、读必重载、禁止重排”这三点,而不是把它当成轻量级锁来用。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
java中boolean的用法
java中boolean的用法

在Java中,boolean是一种基本数据类型,它只有两个可能的值:true和false。boolean类型经常用于条件测试,比如进行比较或者检查某个条件是否满足。想了解更多java中boolean的相关内容,可以阅读本专题下面的文章。

366

2023.11.13

java boolean类型
java boolean类型

本专题整合了java中boolean类型相关教程,阅读专题下面的文章了解更多详细内容。

42

2025.11.30

counta和count的区别
counta和count的区别

Count函数用于计算指定范围内数字的个数,而CountA函数用于计算指定范围内非空单元格的个数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

203

2023.11.20

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

970

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

605

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

294

2025.08.29

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

212

2025.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

294

2025.08.29

JavaScript浏览器渲染机制与前端性能优化实践
JavaScript浏览器渲染机制与前端性能优化实践

本专题围绕 JavaScript 在浏览器中的执行与渲染机制展开,系统讲解 DOM 构建、CSSOM 解析、重排与重绘原理,以及关键渲染路径优化方法。内容涵盖事件循环机制、异步任务调度、资源加载优化、代码拆分与懒加载等性能优化策略。通过真实前端项目案例,帮助开发者理解浏览器底层工作原理,并掌握提升网页加载速度与交互体验的实用技巧。

23

2026.03.06

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 4.2万人学习

C# 教程
C# 教程

共94课时 | 10.8万人学习

Java 教程
Java 教程

共578课时 | 78.4万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号