Java中存在两个最终记录规则,如下所示:
a write to final field in constructor
和the constructed instance reference is assigned to variable afterwards
无法重新排序read a instance reference
和read the final field in the instance afterwards
不能重新排序
我们能把上述规则视为发生在规则之前吗?
a write to final field in constructor
发生在the constructed instance reference is assigned to variable afterwards
之前read a instance reference
发生在read the final field in the instance afterwards
之前
我认为发生在规则语义更强之前。
最后,在我的理解中,final关键字和发生在规则之前的语义保证属于单独的类别。上述推导是错误的,没有必要。
我认为发生在规则语义更强之前。
在这种情况下,最终的重新排序规则肯定更强:
-
发生在规则之前不禁止对语句进行本地重新排序,前提是重新排序后的行为顺序一致;即仅从创建对象的线程的角度来看。
-
相比之下,最终的重新排序规则确实明确禁止构造函数中的某些重新排序,除了那些会违反顺序一致性的规则。
推论:HB不包含最终的重新排序规则。
设计目标是可以使用任何线程的final
字段,而无需任何显式同步或内存模型相关的性能开销;即没有用于读取的存储器屏障。
如果构造函数中允许对final
字段进行本地重新排序,那么另一个线程将需要一个内存屏障来确保它看到受影响字段的一致值。我想不出一种切实可行的方法来优化它。构造函数中不重新排序的潜在小影响(平均而言(小于字段每次读取的读取屏障的影响。