线程启动规则规定主线程调用t.start() happens-before 新线程所有动作,确保start前的共享变量写操作对新线程可见;该规则由JVM在线程真正执行run()时自动建立,仅适用于start()而非直接调用run()。

线程启动规则(Thread start rule)是 Java 内存模型(JMM)中 happens-before 的一条基础规则,它规定:对一个线程的 start() 方法的调用,happens-before 该线程中任意动作的执行。
为什么需要这条规则?
没有这条规则,主线程在调用 t.start() 后设置的共享变量值,新线程可能看不到——因为 JVM 不保证这些写操作对新线程可见。JMM 用 happens-before 关系强制建立这种可见性保障。
换句话说,它让“启动线程前的写”天然对“该线程启动后的读/写”可见,无需额外同步(如 volatile 或 synchronized)。
规则怎么生效?
这条规则不是靠代码语法触发的,而是由 JVM 在线程实际开始执行(即从 run() 方法入口进入)时自动建立的内存语义约束。关键点:
立即学习“Java免费学习笔记(深入)”;
-
仅适用于
start(),不适用于直接调用run()(后者只是普通方法调用,不创建新线程,也不触发 happens-before) - 主线程中
start()调用之前的全部动作(包括对共享变量的写),都对新线程的首次执行动作构成 happens-before - 它不保证新线程立即看到所有变更,但保证这些变更不会被重排序到
start()之后,且最终会对其可见(符合 JMM 的最终一致性要求)
一个典型例子
假设主线程执行:
int x = 42; // A
boolean flag = true; // B
Thread t = new Thread(() -> {
System.out.println(x); // C(可能输出 42)
System.out.println(flag); // D(一定输出 true)
});
t.start(); // E(happens-before C 和 D)
根据线程启动规则,E happens-before C,且 A、B 都 happens-before E(程序顺序规则),因此 A、B 也 happens-before C/D。所以 D 一定看到 true;C 一般也能看到 42(除非发生严重指令重排且无其他同步,但 JMM 禁止这种破坏 happens-before 的重排)。
和其它规则的关系
线程启动规则常与程序顺序规则、监视器锁规则等协同工作。例如:
- 它不替代锁或 volatile —— 若主线程在
start()后再修改变量,新线程仍可能看不到 - 它只管“启动那一刻”的可见边界,不负责线程运行期间的持续同步
- 配合
join()的线程终止规则,可构建完整的线程间通信链


















