找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

4158

积分

0

好友

559

主题
发表于 1 小时前 | 查看: 1| 回复: 0

Java 内存模型(JMM)是并发编程的基石。只有真正理解 JMM,你才能透彻掌握 volatilesynchronized 以及内存可见性等并发核心概念的底层逻辑,而不仅仅是死记硬背面试题。

JMM 是什么?

JMM,即 Java Memory Model,它定义了一套Java多线程访问共享内存的规则与规范。这里的关键词是“规范”——JMM 规定了一组保证,描述了线程如何通过内存进行交互,但它本身并非内存的物理实现或运行时数据区的划分。

它的核心目标非常明确:为了解决在多线程环境下产生的可见性原子性有序性三大经典问题。

运行时内存划分

要理解 JMM 的规则,先要了解 Java 运行时内存的大致划分,这有助于我们理解“主内存”与“工作内存”的抽象概念。内存主要分为两大类:

线程私有(每个线程独享一份):

  • 程序计数器:记录当前线程所执行的字节码行号指示器。
  • 虚拟机栈:用于存储方法调用栈帧,包含局部变量表、操作数栈等信息。
  • 本地方法栈:为 Native 方法服务。

线程共享(所有线程可见):

  • :存放对象实例,这是 JMM 规范中“主内存”概念的主要部分。
  • 方法区:存储已被加载的类信息、常量、静态变量等数据。

可见性:线程间的“通知”机制

可见性问题,简单说就是:一个线程修改了共享变量的值,另一个线程却未必能立即看到这个更新。

为什么会出现这种情况?这源于 JMM 的抽象:每个线程都有一个自己的“工作内存”(可以理解为 CPU 缓存、寄存器等的抽象),线程对共享变量的操作会先在工作内存中进行,之后再同步回主内存。如果线程 A 将修改写回了主内存,但线程 B 没有及时去主内存读取最新的值,而是继续使用自己工作内存中的旧副本,问题就产生了。

volatile 关键字正是为了解决可见性问题而生的。它强制规定,对该变量的每一次读写都必须直接穿透工作内存,与主内存交互,从而保证了修改对所有线程的立即可见性。理解这一点是掌握 volatile 的基础,也是后端与架构知识体系中并发部分的关键。

原子性:不可分割的操作

原子性意味着一个操作是不可中断的,要么全部执行成功,要么完全不执行,不会出现中间状态。

一个典型的非原子操作例子就是 i++。它看似一行代码,实际上包含了三个独立的步骤:1)读取变量 i 的值;2)将 i 的值加 1;3)将新值写回 i。如果两个线程同时执行 i++,就可能出现两个线程都读取了相同的初始值,然后各自加1写回,导致最终结果只增加了1,而不是预期的2。

要保证这类复合操作的原子性,可以使用 synchronized 关键字(同步代码块)或 java.util.concurrent.atomic 包下的原子类,如 AtomicInteger

有序性:指令重排序的“双刃剑”

为了提高程序执行效率,处理器和编译器在不影响单线程执行结果的前提下,会对指令进行重新排序优化。这就是指令重排序

然而,这种优化在多线程环境下就可能成为隐患。因为重排序的前提——“不影响单线程结果”在多个线程交织执行时可能被破坏,导致程序出现意想不到的行为。

synchronizedvolatile 都具备禁止特定范围内指令重排序的内存语义,从而保证了有序性。

Happens-Before 规则

JMM 为程序员提供了一套强而有力的心智模型和保证——Happens-Before 规则。它描述了两个操作之间的偏序关系,如果操作 A “happens-before” 操作 B,那么 A 的所有修改对 B 都是可见的,且 A 的执行顺序排在 B 之前。

几条核心的 Happens-Before 规则包括:

  • 程序顺序规则:在同一个线程中,按照控制流顺序,前面的操作 happens-before 后面的操作。
  • volatile 变量规则:对一个 volatile 变量的写操作 happens-before 后续任意对这个 volatile 变量的读操作。
  • 传递性规则:如果 A happens-before B,且 B happens-before C,那么 A happens-before C。

掌握这些规则,能帮助你在不依赖底层实现细节的情况下,准确推断并发程序的执行结果。

总结

Java内存模型(JMM) 是贯穿整个 Java 并发编程体系的核心理论。无论是 volatilesynchronized、显式锁 (Lock),还是并发容器,其行为最终都由 JMM 的规则来定义和约束。

Java开发者而言,深入理解 JMM 不仅是为了应对技术面试,更是为了在实战中能够编写出正确、高效且可维护的并发程序。如果你想在云栈社区与更多开发者探讨这类计算机底层原理,或者寻找更多计算机基础相关的学习资料,这里会是一个不错的起点。




上一篇:深度对比 MiniMax M2.7 与小米 MiMo-V2-Pro:两大 Agent 模型的技术路线与上手选择
下一篇:告别Selenium?微软Magentic-UI:基于AI的网页自动化新方案
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-3-20 08:32 , Processed in 0.642066 second(s), 41 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表