讲师中心 微信公众号
AI工具推荐 视频效率加速

在Java里volatile关键字如何保证内存可见性_Java多线程同步解析

轻杰小哥_5247

轻杰小哥_5247

发布时间:2026-02-10 16:03:27

|

782人浏览过

|

来源于php中文网

原创

volatile仅保证可见性和有限有序性,不保证原子性;synchronized则同时保证可见性、原子性和有序性,适用于临界区保护和多变量协同场景。

在java里volatile关键字如何保证内存可见性_java多线程同步解析

volatile 怎么让线程看到最新值

它不加锁,但强制每次读都从主内存取,每次写都立刻刷回主内存。JVM 禁止对 volatile 变量的普通读写重排序,也禁止将其与前后指令重排(有 happens-before 语义)。

常见错误现象:多个线程轮询一个标志位(如 running = false),但没加 volatile,导致某个线程永远看不到修改,死循环卡住。

  • 仅适用于「单次读/写原子性」场景:boolean、int、long(64位 JVM 上 long 读写是原子的)、引用类型赋值
  • 不保证复合操作原子性:比如 counter++(读-改-写三步)即使 counter 是 volatile,依然会出错
  • 不能替代 synchronized 做临界区保护,比如需要同时更新两个变量时,volatile 无法保证二者状态一致

volatile 和 synchronized 的关键区别在哪

synchronized 既保证可见性,也保证原子性和有序性;volatile 只保可见性和有序性(且是有限制的有序性)。

使用场景差异明显:

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

JavaStoryDevelop
JavaStoryDevelop

你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在

下载
  • 用 volatile:状态标志(isShutdown)、一次性安全发布(如双重检查锁里的 instance)、与 LockSupport 配合的简单信号通知
  • 用 synchronized:需要互斥访问共享资源、涉及多个变量协同、或需等待/通知机制(wait/notify)
  • 性能上,volatile 无上下文切换和锁竞争开销,但每次读写都有内存屏障成本;synchronized 在无竞争时已很轻量(偏向锁、轻量级锁优化),但高竞争下代价明显

为什么 volatile 不能防止指令重排序

它本身不“防止”重排序,而是通过插入内存屏障(Memory Barrier)来约束重排序范围。JVM 在编译和运行时仍可能重排,但必须满足屏障的语义限制。

例如:volatile 写之前的所有普通写,不能被重排到该写之后;volatile 读之后的所有普通读,不能被重排到该读之前。

  • JSR-133 定义了 4 种屏障:LoadLoad、StoreStore、LoadStore、StoreLoad —— volatile 读/写各对应不同组合
  • 注意:这些屏障只对当前变量生效,不影响其他非 volatile 变量之间的重排顺序
  • 典型坑:以为给一个 flag 加了 volatile,就能保证它前面初始化对象的操作一定对其它线程可见 —— 实际上,若对象字段没用 volatile 或同步保护,仍可能看到半初始化状态(需配合安全发布模式)

Java 9+ 中 VarHandle 对 volatile 的替代价值

VarHandle 提供更细粒度的内存访问控制,比如可以用 getVolatile() / setVolatile() 模拟 volatile 字段语义,还能对数组元素、堆外内存做类似操作。

但它不是“取代”,而是补充:

  • 动态获取字段句柄(反射式),适合泛型工具类或框架层封装
  • 支持更多访问模式:如 getAcquire() / setRelease()(比 volatile 更弱的语义,开销略低)
  • 普通业务代码没必要替换 —— 直接用 volatile 字段更清晰、JIT 更友好;只有在需要运行时决定访问目标或绕过字段限制时才考虑 VarHandle

真正容易被忽略的是:volatile 修饰的 long/double 在 32 位 JVM 上仍存在非原子读写风险(虽然现在基本没人用了),以及它完全不管 CPU 缓存一致性协议(MESI)底层细节——你看到的“立即可见”,其实是 JVM + 硬件共同协作的结果,不是魔法。

热门AI工具

更多
VibeKnow
VibeKnow Hot

一款AI视频创作工具,主要用于全球首个AI知识视频创作平台,文档、文章、网页,一键生成视频,适合需要提升相关任务效率的用户。

UpDream
UpDream Hot

一款AI视频创作工具,主要用于哔哩哔哩推出的自研AI视频创作工具,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

PixPix
PixPix Hot

PixPix是一款面向电商视觉生产的AI商品图生成工具。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

讯飞绘文

讯飞绘文是一款由科大讯飞推出的一站式 AIGC 内容运营平台。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

SkildArt
SkildArt Hot

SkildArt是一款AI文本写作工具,一站式 AI 视觉创作平台。

切问学术

切问学术是一款AI论文写作工具,复旦大学NLP团队推出的AI学术智能体。

相关专题

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

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

2130

2023.11.13

java boolean类型
java boolean类型

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

163

2025.11.30

string转int
string转int

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

6619

2023.08.02

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

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

3205

2024.08.29

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

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

4148

2025.08.29

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

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

2845

2025.08.29

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

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

4148

2025.08.29

C++中int、float和double的区别
C++中int、float和double的区别

本专题整合了c++中int和double的区别,阅读专题下面的文章了解更多详细内容。

784

2025.10.23

Gradle插件开发入门教程
Gradle插件开发入门教程

本专题介绍Gradle插件开发的基本流程,涵盖插件类编写、自定义任务注册、扩展参数设计和插件应用方法,帮助你理解插件如何组织构建逻辑,减少多个项目之间的重复配置。

40

2026.10.22

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
dev.java 官方:Learn Java
dev.java 官方:Learn Java

共0课时 | 0人学习

Java JDBC数据库连接官方教程
Java JDBC数据库连接官方教程

共0课时 | 0人学习

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

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn