java内存模型(jmm)是一套规范,定义多线程环境下共享变量的读写规则,核心解决可见性、原子性、有序性问题:可见性指线程修改对其他线程是否立即可见;原子性指操作不可中断;有序性指禁止导致逻辑错误的指令重排。

Java 内存模型(JMM)不是物理内存结构,而是一套规范,用来定义多线程环境下变量读写行为的规则。它解决的核心问题就是:当多个线程操作同一个共享变量时,怎样保证程序行为是可预期的。关键就落在三个特性上——可见性、原子性、有序性。
可见性:一个线程改了,另一个线程能不能马上看到?
线程不直接读写主内存,而是把变量拷贝一份到自己的工作内存(比如 CPU 缓存)中操作。改完后,什么时候写回主内存是不确定的。这就导致另一个线程可能一直读着旧值。
Java Linux版下载入口,提供 Oracle JDK 26.0.2 官方 Linux 安装包、Java 环境配置、JDBC 数据库连接和 Java 服务端开发相关信息。
- 典型表现:比如一个 boolean flag 被线程 A 设为 true,线程 B 却始终在 while(!flag) 中死循环——因为没看到更新。
-
保障手段:
- volatile:强制每次读都从主内存取,每次写都立刻刷回主内存,并让其他线程缓存失效;
- synchronized:解锁前必须把修改同步回主内存,加锁时清空工作内存,迫使重新读取;
- final:构造完成后的 final 字段,对其他线程天然可见(前提是构造过程中 this 没逸出)。
原子性:一个操作是不是“一步到位”,不会被中途打断?
看似简单的一行代码,比如 i++,其实包含“读 i → 加 1 → 写回 i”三步。多线程下,这两步可能交错执行,造成结果丢失。
- 基本类型读写默认原子:int、boolean 等的单纯赋值(如 i = 5)是原子的;但 long/double 在 32 位 JVM 上可能非原子(不过现代 JVM 基本已修复)。
- 复合操作非原子:i++、count++、对象引用赋值后再调用方法等,都不保证原子性。
-
保障手段:
- synchronized:用锁把一段逻辑包裹起来,同一时刻只允许一个线程执行;
- Lock 接口(如 ReentrantLock):提供更灵活的锁控制;
- java.util.concurrent.atomic 包下的类(如 AtomicInteger):底层基于 CAS 指令,无锁实现高效原子更新。
有序性:代码写的顺序,是不是就按这个顺序执行?
为了提升性能,编译器和 CPU 可能对指令重排序。单线程下不影响结果,但多线程下,如果依赖某条语句“一定先发生”,重排就可能破坏逻辑。
- 常见陷阱:双重检查锁定(DCL)中,new 对象可能被重排为“分配内存 → 设置 final 字段 → 构造函数执行”,导致其他线程拿到未初始化完成的对象。
-
保障手段:
- volatile:不仅保证可见性,还禁止其前后指令与 volatile 读写发生重排序;
- synchronized:进入/退出同步块隐含 happens-before 关系,天然限制重排范围;
- happens-before 规则:这是 JMM 定义的最根本的有序性保障,比如“监视器锁规则”“volatile 变量规则”“程序次序规则”等,只要满足其中一条,就能确保前一个操作的结果对后一个操作可见且有序。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










