Java内存模型 JMM 看这一篇就够了
1. 计算机硬件存储体系计算机存储结构从本地磁盘到主存到CPU缓存也就是从硬盘到内存到CPU。一般对应的程序的操作就是从数据库查数据到内存然后到CPU进行计算。因为有这么多级的缓存(cpu和物理主内存的速度不一致的)CPU 的运行并不是直接操作内存而是先把内存里边的数据读到缓存而内存的读和写操作的时候就会造成不一致的问题。Java 虚拟机规范中试图定义一种Java内存模型java Memory Model简称JMM) 来屏蔽掉各种硬件和操作系统的内存访问差异以实现让 Java 程序在各种平台下都能达到一致的内存访问效果。推导出我们需要知道 JMM。JMM (Java内存模型Java Memory Model简称JMM) 本身是一种 **抽象的 **概念并不真实存在它仅仅描述的是一组约定或规范通过这组规范定义了程序中(尤其是多线程)各个变量的读写访问方式并决定一个线程对共享变量的写入何时以及如何变成对另一个线程可见关键技术点都是围绕多线程的原子性、可见性和有序性展开的。原则JMM 的关键技术点都是围绕多线程的原子性、可见性和有序性展开的。能干嘛通过JMM来实现线程和主内存之间的抽象关系。屏蔽各个硬件平台和操作系统的内存访问差异以实现让Java程序在各种平台下都能达到一致的内存访问效果。2. JMM规范定义的三大特性2.1 可见性是指当一个线程修改了某一个共享变量的值其他线程是否能够立即知道该变更JMM规定了所有的变量都存储在主内存中。Java 中普通的共享变量不保证可见性因为数据修改被写入内存的时机是不确定的多线程并发下很可能出现脏读所以每个线程都有自己的工作内存线程自己的工作内存中保存了该线程使用到的变量的主内存副本拷贝线程对变量的所有操作读取赋值等 都必需在线程自己的工作内存中进行而不能够直接读写主内存中的变量。不同线程之间也无法直接访问对方工作内存中的变量线程间变量值的传递均需要通过主内存来完成2.2 原子性指一个操作是不可中断的即多线程环境下操作不能被其他线程干扰。2.3 有序性对于一个线程的执行代码而言我们总是习惯性认为代码的执行总是从上到下有序执行。但为了提供性能编译器和处理器通常会对指令序列进行重新排序。指令重排可以保证串行语义一致但没有义务保证多线程间的语义也一致即可能产生脏读简单说两行以上不相干的代码在执行的时候有可能先执行的不是第一条不见得是从上到下顺序执行执行顺序会被优化。单线程环境里面确保程序最终执行结果和代码顺序执行的结果一致。处理器在进行重排序时必须要考虑指令之间的数据依赖性多线程环境中线程交替执行,由于编译器优化重排的存在两个线程中使用的变量能否保证一致性是无法确定的,结果无法预测。3. JMM规范下多线程对变量的读写过程3.1 读取过程由于 JVM 运行程序的实体是线程而每个线程创建时JVM都会为其创建一个工作内存(有些地方称为栈空间)工作内存是每个线程的私有数据区域而Java内存模型中规定所有变量都存储在主内存主内存是共享内存区域所有线程都可以访问但线程对变量的操作(读取赋值等)必须在工作内存中进行首先要将变量从主内存拷贝到的线程自己的工作内存空间然后对变量进行操作操作完成后再将变量写回主内存不能直接操作主内存中的变量各个线程中的工作内存中存储着主内存中的变量副本拷贝因此不同的线程间无法访问对方的工作内存线程间的通信(传值)必须通过主内存来完成其简要访问过程如下图:3.2 JMM 定义了线程和主内存之间的抽象关系线程之间的共享变量存储在主内存中(从硬件角度来说就是内存条)每个线程都有一个私有的本地工作内存本地工作内存中存储了该线程用来读/写共享变量的副本(从硬件角度来说就是CPU的缓存比如寄存器、L1、L2、L3缓存等)3.3 总结我们定义的所有共享变量都存储在物理主内存中。每个线程都有自己独立的工作内存里面保存该线程使用到的变量的副本主内存中该变量的一份拷贝。线程对共享变量所有的操作都必须先在线程自己的工作内存中进行后写主内存不能直接从主内存中读写。不同线程之间也无法之间访问其他线程的工作内存中的变量线程间变量的传递需要通过主内存来进行。4. happens-before在 JMM 中如果一个操作执行的结果需要对另一个操作性可见性或者代码重排序那么这两个操作之间必须存在 happens-before 关系。案例先行发生原则说明如果 Java 内存模型中所有的有序性都仅靠 volatile 和 synchronized 来完成那么有很多操作都将会变得非常啰嗦但是我们在编写 Java 并发代码的时候并没有察觉到这一点。我们没有时时、处处、次次添加volatile和synchronized来完成程序这是因为Java语言中JMM原则下有一个“先行发生”(Happens-Before)的原则限制和规矩。这个原则非常重要它是判断数据是否存在竞争线程是否安全的非常有用的手段。依赖这个原则我们可以通过几条简单规则一揽子解决并发环境下两个操作之间是否可能存在冲突的所有问题而不需要陷入 Java 内存模型苦涩难懂的底层编译原理之中。Happens-Before 总原则如果第一个操作 Happens-Before 另一个操作 那么第一个操作的执行结果将对第二个操作可见而且第一个操作的执行顺序在第二个操作之前。两个操作之间存在 Happens-Before 关系 并不意味着一定要按 Happens-Before 原则指定的顺序来执行。如果重排序之后的执行结果与按照 Happens-Before 关系来执行的结果一致那么这种重排序并不非法。Happens-Before 8 条次序规则锁定规则volatile变量规则传递规则线程启动规则Thread 对象的 start() 方法先行发生于此线程的每一个动作线程中断规则线程终止规则对象终结规则

相关新闻

Linux MySQL定时备份脚本实战:mysqldump+crontab自动化与恢复验证

Linux MySQL定时备份脚本实战:mysqldump+crontab自动化与恢复验证

简介:Linux环境下MySQL定时备份脚本是一份面向运维工程师和数据库管理人员的实用工具包,用于解决Linux服务器中数据库定期备份、压缩存储与过期备份清理等常见运维需求。压缩包共2个文件,包含1个shell备份脚本和1个txt定时任务配置说明&#…

2026/10/13 7:44:17 阅读更多 →
概率数据结构实战:布隆过滤器与Count-Min Sketch解决缓存穿透与频次统计

概率数据结构实战:布隆过滤器与Count-Min Sketch解决缓存穿透与频次统计

1. 先从一道“理论题”说起:缓存穿透击穿了我的服务大概两年前,我当时负责的一个读多写少的服务突然扛不住了。流量高峰时,Redis里明明有缓存,但数据库的查询量还是飙到了平时的十倍。查了半天,发现问题不在缓存过期&a…

2026/10/13 7:44:41 阅读更多 →
NopCommerce实体设计:BaseEntity、继承策略与EF Core映射实践

NopCommerce实体设计:BaseEntity、继承策略与EF Core映射实践

1. 从"每张表都要Id"说起:BaseEntity到底省了多少事接触NopCommerce的开发者,不管是刚把源码拉下来准备二次开发,还是已经在做电商定制项目,第一眼翻开Nop.Core项目,大概率都会看到BaseEntity这个类。如果你…

2026/10/13 10:24:24 阅读更多 →

最新新闻

金融时间序列建模全流程:从平稳性检验到GARCH波动率预测

金融时间序列建模全流程:从平稳性检验到GARCH波动率预测

1. 从第一节课到第四章:金融时间序列到底在研究什么如果你正在啃金融相关的课程,大概率会在一门叫《金融时间序列分析》或类似名字的课上卡住。这门课和传统统计学、计量经济学都不一样,它研究的是股票收益率、汇率波动、债券利差这类有“先后…

2026/10/14 0:48:55 阅读更多 →
AgenticOps工程:企业自动化运维的自主决策革命

AgenticOps工程:企业自动化运维的自主决策革命

1. AgenticOps Engineering 的本质与价值AgenticOps Engineering 正在重新定义企业自动化运维的边界。与传统自动化工具不同,这种新型工程范式通过赋予系统自主决策能力,使企业IT基础设施能够像拥有"数字员工"一样主动感知环境变化、预测问题并…

2026/10/14 0:48:55 阅读更多 →
用插件重构知识工作流:浏览器、编辑器与知识库的自动化实践

用插件重构知识工作流:浏览器、编辑器与知识库的自动化实践

知识工作者这个词听起来有点抽象,但落到日常就非常具体:你可能天天在写方案、查资料、写代码、记笔记、做汇报,一天结束回头一看,真正用在"思考"上的时间反而不多,大量时间被复制粘贴、切换窗口、找文件、重…

2026/10/14 0:48:55 阅读更多 →
ABAP单元测试效率提升:ADT工具链实战

ABAP单元测试效率提升:ADT工具链实战

1. 项目概述:当ABAP单元测试遇上效率革命在SAP开发领域,ABAP Unit作为核心测试框架已经存在多年,但真正能将其融入日常开发的团队却不多见。问题不在于框架本身,而在于传统测试流程中存在太多效率断层——从编写测试用例到执行测试…

2026/10/14 0:48:55 阅读更多 →
Python远程批量关机实战:WinRM/WMI/SMB三路径选型与避坑

Python远程批量关机实战:WinRM/WMI/SMB三路径选型与避坑

简介:本资源是一份面向Windows系统管理员与IT运维人员的Python自动化脚本工具包,解决多台设备集中管理场景下的远程批量关机需求,适用于机房巡检、课室终端维护、故障应急处置等实际运维任务。压缩包共3个文件(923B)&a…

2026/10/14 0:48:55 阅读更多 →
尖叫声音样本数据集eva:从包结构到训练基线的完整实践

尖叫声音样本数据集eva:从包结构到训练基线的完整实践

简介:EVA尖叫声音样本数据集是一份面向音乐信息检索(MIR)与音频分类研究的人声尖叫样本库,由台湾清华大学MIR课程项目整理,旨在为尖叫检测、异常声音识别、SVM分类等实验提供稀缺的领域数据。压缩包共63个文件&#xf…

2026/10/14 0:47:55 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 22:01:27 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →