理解 JVM 的 8 个原子操作与 `volatile` 的语义

理解 JVM 的 8 个原子操作与 volatile 的语义

在并发编程中,volatile 常常被提及。但要真正理解它的作用,需要先回到 Java 内存模型(JMM) 的基础:线程与主内存之间的交互。JMM 定义了 8 个原子操作 来描述这些交互过程,而 volatile 的语义正是基于它们实现的。


JVM 的 8 个原子操作

JMM 把 主内存 、工作内存 和 执行引擎 的数据交互拆分成了 8 个最小操作,这些操作是并发语义的基石:

  1. lock(锁定)

    将主内存中的变量标记为某个线程独占。

  2. unlock(解锁)

    解除独占标记,使变量可被其他线程访问。

  3. read(读取)

    从主内存中读取变量值,传输到线程的通道。

  4. load(载入)

    将 read 到的值写入线程工作内存的变量副本。

  5. use(使用)

    将工作内存中的值传给执行引擎使用。

  6. assign(赋值)

    将执行引擎计算后的值赋给工作内存中的变量副本。

  7. store(存储)

    将工作内存的值传输到通道。

  8. write(写入)

    将 store 传来的值写入主内存。


四组配对关系

这 8 个操作其实是 四组成对动作:

  • lock / unlock:保证变量在某一时刻只有一个线程独占。
  • read / load:把主内存的值带入工作内存。
  • store / write:把工作内存的值写回主内存。
  • use / assign:工作内存与执行引擎之间的数据交互。

示意图:

主内存 <──read/load──> 工作内存 <──use/assign──> 执行引擎

^ │

└─────────────store/write───────────┘

其中 use/assign 仅在 线程内部 发生,对跨线程的可见性影响不大,因此开发者平时不太关心它。


volatile 的语义

volatile 并不会改变 8 个原子操作的存在方式,而是通过 内存屏障 来影响其中部分操作的执行顺序和可见性:

  1. 保证可见性

    • 写入 volatile 变量:强制执行 store → write,立即刷新主内存。
    • 读取 volatile 变量:强制执行 read → load,直接从主内存取值。
  2. 保证有序性

    • 在 volatile 写操作前后,JVM 插入 StoreStore、StoreLoad 屏障,防止指令重排。
    • 在 volatile 读操作后,插入 LoadLoad、LoadStore 屏障,确保读到的值对后续操作可见。
  3. 不保证原子性

    • volatile 只能保证单次读/写的原子性。
    • 对于复合操作(如 count++),依然会分解成多步(read → load → use → assign → store → write),在多线程下可能出现 丢失更新。

为什么 use / assign 看似多余?

有人会觉得 use/assign 没有必要,因为我们写代码时从未直接操作过它。实际上:

  • read/load、store/write 关注的是 线程与主内存之间 的数据交换。
  • use/assign 关注的是 线程工作内存与执行引擎之间 的交互。

这部分虽然我们平时感知不到,但在 JMM 的规范 层面,它是必须被定义的,否则无法保证指令级别的精确定义。


总结

  • JVM 的 8 个原子操作分别是:lock / unlock / read / load / use / assign / store / write。
  • 它们可以配对为四组:
    • lock/unlock
    • read/load
    • store/write
    • use/assign
  • volatile 主要约束的是 read+load、store+write ,配合内存屏障保证 可见性 + 有序性。
  • volatile 不保证复合操作的原子性 ,如果需要保证,需要 CAS 或 锁。

✍️ 记住一句话:
volatile 让读写操作直达主内存,并通过内存屏障保证顺序,但不会把复合操作变成原子操作。

相关推荐
2301_780789662 小时前
跨平台适配!SDK 游戏盾兼容全终端游戏场景
java·网络·ddos
学长毕设3 小时前
基于springboot的食品仓库管理系统
java·spring boot·后端
步行cgn3 小时前
FormHttpMessageConverter 详解:Spring MVC 中表单数据的读写转换器
java·spring·mvc
龙亘川3 小时前
构建城市公共安全数字底座:亘川智城智慧安防系统全维度解读
java·大数据·开发语言·人工智能·信息可视化
金銀銅鐵3 小时前
[Java] 用 CLI 展示 EnumMap 增删键值对时的内部变化
java·源码·ai编程
秋天的怀念_David4 小时前
第二十二夜 · 数字迷雾
java·程序人生·算法
Raas1004 小时前
AI网关部署方案?从部署到上线全流程
java·开发语言·人工智能·gateway·ai网关·企业级ai网关·企业级ai产品
niucloud-admin4 小时前
NIUCLOUD PHP SAAS上门家政使用文档:城市管理
java·前端·php
霸道流氓气质5 小时前
智能客服组件:分层意图识别、RAG Advisor 与人工转接状态机的 Vue3 + Spring AI 生产级实战
java·人工智能·spring
captain3765 小时前
MyBatis操作数据库(入门2)
java·数据库·spring boot·后端·spring·mybatis