我们可以将 Java 中的最终重新排序规则视为先行规则吗?

Can we treat final reorder rule in Java as happens-before rule?

Java中存在两条最终记录规则,如下:

  1. a write to final field in constructorthe constructed instance reference is assigned to variable afterwards 无法重新排序
  2. read a instance referenceread the final field in the instance afterwards 无法重新排序

我们可以将上述规则视为 happen-before 规则吗?

  1. a write to final field in constructor 发生在 the constructed instance reference is assigned to variable afterwards
  2. 之前
  3. read a instance reference 发生在 read the final field in the instance afterwards
  4. 之前

我认为 happens-before 规则语义更强。

最后我的理解是,final关键字的语义保证和happens-before规则是分开的categories.The上面的推导是错误和不必要的。

I think happens-before rule is stronger semantic.

最终的重新排序规则肯定更强,在这种情况下:

  • happens-before规则不会禁止在本地重新排序语句,前提是重新排序后的行为是顺序一致;即仅从创建对象的线程的角度来看。

  • 相比之下,最终的重新排序规则 确实 明确禁止构造函数中的某些重新排序,除了那些会违反顺序一致性.

推论:HB 不包含最终的重新排序规则。

(如果确实如此,那么根本就没有必要声明后者。但是 JLS 作者不会仅仅为了它而添加这些东西。给他们和成千上万的人其他读过/研究过这些东西的人的一些信用。)


设计目标是可以从任何线程使用 final 字段,而无需任何显式同步或内存模型相关的性能开销;即没有读取内存障碍。

如果在构造函数中允许对 final 字段进行本地重新排序,那么另一个线程将需要一个内存屏障来确保它看到受影响字段的一致值。我想不出一种实用的方法来优化它。在构造函数中不重新排序的潜在小影响(平均而言)小于读取屏障对字段的每次读取的影响。