JSR-133 (Java Specification Request 133)是 Java 平台中一项具有里程碑意义的规范,全称为 《Java™ 内存模型与线程规范》 (Java Memory Model and Thread Specification )。它由 Java Community Process(JCP)于 2000 年发起,最终在 Java 5.0(Tiger,2004 年发布) 中正式引入,彻底重构了 Java 的并发语义基础。
一、为什么需要 JSR-133?
在 Java 1.0 到 1.4 时代,原始的 Java 内存模型(定义在《Java 语言规范》第 17 章)存在严重缺陷:
- final 字段可能被看到"中途状态" :即使对象构造完成,其他线程仍可能看到
final字段的默认值(如 0 或 null),破坏不可变性。 - 允许"凭空造值"(out-of-thin-air values):理论上可能出现逻辑上不可能的值(如一个 int 变量从未被赋值为 42,却有线程读到 42)。
- 过度限制编译器和 CPU 优化:为了"安全",禁止了许多合法的重排序,影响性能。
- 语义模糊:开发者难以准确预测多线程程序的行为。
这些问题使得编写正确、高效的并发程序极其困难。
二、JSR-133 的核心目标
-
✅ 保留并强化安全性
- 禁止"无中生有"的值(out-of-thin-air safety)。
- 确保类型安全、内存安全等基本保障不受影响。
-
✅ 提供清晰的内存可见性语义
- 引入 happens-before 关系作为核心机制,明确定义哪些操作对其他线程可见。
-
✅ 保证 final 字段的安全发布(Initialization Safety)
如果一个对象被正确构造 (即构造期间
this引用未逸出),那么所有线程在看到该对象引用时,无需同步 即可看到其final字段的正确值。 -
✅ 支持高性能 JVM 实现
- 允许在不破坏语义的前提下进行编译器优化(如指令重排)和硬件优化(如缓存、乱序执行)。
-
✅ 最小化对现有代码的影响
- 正确同步的程序行为不变;仅修复错误或未定义行为。
三、JSR-133 引入的关键机制
| 机制 | 说明 |
|---|---|
| happens-before 关系 | 定义操作间的可见性顺序(如 volatile 写 → volatile 读) |
重新定义 volatile |
禁止 volatile 变量周围的重排序,并建立跨线程的 happens-before 边界 |
强化 final 语义 |
保证 final 字段在构造完成后对所有线程立即可见 |
| 明确 synchronized 语义 | 锁的释放与获取之间建立 happens-before 关系 |
| 定义未同步程序的行为 | 虽不保证正确性,但限制其危害(如不允许凭空造值) |
四、实际影响举例
✅ 场景:安全发布不可变对象
java
public class ImmutablePoint {
public final int x, y;
public ImmutablePoint(int x, int y) {
this.x = x;
this.y = y;
}
}
// 线程1:发布对象
ImmutablePoint p = new ImmutablePoint(1, 2);
// 线程2:使用对象
if (p != null) {
System.out.println(p.x); // JSR-133 保证这里一定输出 1,而非 0!
}
在旧内存模型下,可能看到
x=0;JSR-133 修复了此问题。
✅ 场景:volatile 保证可见性
java
volatile boolean running = true;
// 线程1
while (running) { ... }
// 线程2
running = false; // 其他线程能立即看到此修改
五、JSR-133 的历史地位
- 是 现代 Java 并发编程的基石。
- 为
java.util.concurrent(JUC)包的实现提供了语义基础。 - 影响了后续 C++11、C# 等语言的内存模型设计。
- 使 Java 成为少数拥有形式化、严谨、跨平台内存模型的主流语言之一。
六、延伸阅读建议
- 官方 FAQ:http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html
- 核心论文:The Java Memory Model by Jeremy Manson, William Pugh et al.
- 书籍:《Java 并发编程实战》(Brian Goetz)第 3 章
总结
JSR-133 不是一次小修补,而是一场并发语义的革命。它用 happens-before 模型取代了模糊的"主存/工作内存"比喻,为 Java 提供了既安全又高效、既严谨又实用的多线程内存语义。
没有 JSR-133,就没有今天可靠的 Java 并发生态。