⭐ 推荐:社区规则条款 V1.0

Java 的 happens-before 规则到底怎么理解?

chinaz
chinaz 归队站长新人站长
发布于 2026-10-13 14:00 ·0 浏览 ·2 回复
内容摘要

happens-before 并非时间先后,而是前操作结果对后操作可见且不被重排的承诺,JMM 用 JLS 的程序顺序、锁、volatile、线程启动终止、中断、终结器和传递性八条规则落地判断,缺少该关系只代表允许出错,不能以运行结果作为正

版权声明:本文来自 GJ站长论坛《Java 的 happens-before 规则到底怎么理解?》
原文链接:https://www.gj0.com/thread-1819.html
转载请注明出处并保留本声明;内容仅代表作者观点,与本站立场无关。若本文涉嫌侵权,请联系本站处理。
—/ 5暂无评分
还没有评分,来打第一分吧

全部回复 2

周末
周末 新人站长 1楼 2026-10-13 14:25

这篇的推导链条没问题,但要真正拿来落地,得补两个前提:volatile 规则只在“读确实观察到了那次写”时才成立,而且 hb 应该是你验证方案的工具,不是写代码时反推的依据。

liulian
liulian 归队站长新人站长 #1132 2楼 2026-10-13 14:43
周末:这篇的推导链条没问题,但要真正拿来落地,得补两个前提:volatile 规则只在“读确实观察到了那次写”时才成立,而且 hb 应该是你验证方案的工具,不是写代码…

周末这两点补得很关键,尤其“读必须观察到那次写”,是 volatile 规则从规范条文落到代码可见性的闸门。

严格说,JLS 的表述是“volatile 写 happens-before 后续对同一字段的读”,这个“后续”是在同步顺序里讲的;落到你那段代码,就是 t2 的 while(!flag) 必须真的读到 t1 写入的 true,才能把 A 对 data 的写通过 B→C→D 传递过来。如果读端看到的是旧值或另一个写,就不能拿这条 volatile 边去证明前面普通字段的可见性。所以条件等待要用 while 而不是 if,本质就是逼着读端持续观察,直到观测到目标写。

第二点也同意:happens-before 是验证方案的工具,不是写代码时反推的依据。落地顺序应该是先定同步契约——谁发布、谁获取、用锁还是 volatile、要不要 join——再用 hb 链条检查有没有缺口。反过来为了凑 hb 规则去堆 volatile,很容易写出看着安全、实际漏掉观察条件或原子性的代码。

常见坑:volatile 不保证 i++ 这类复合操作原子性;