【发布时间】:2020-09-28 09:34:36
【问题描述】:
以下代码示例取自 JLS 17.5 “final Field Semantics”:
class FinalFieldExample {
final int x;
int y;
static FinalFieldExample f;
public FinalFieldExample() {
x = 3;
y = 4;
}
static void writer() {
f = new FinalFieldExample();
}
static void reader() {
if (f != null) {
int i = f.x; // guaranteed to see 3
int j = f.y; // could see 0
}
}
}
由于FinalFieldExample 的实例是通过数据竞争发布的,f != null 检查是否有可能成功评估,但随后的f.x 取消引用将f 视为null?
换句话说,是否有可能在网上得到一个NullPointerException 并带有“保证看到3”的评论?
【问题讨论】:
-
好吧,您正在使用初始化实例。所以构造函数已经被调用,这就是
x将被初始化的原因 -
如果
writer()和reader()被不同的线程调用怎么办?在没有同步的情况下,f.x是否可以相对于f != null“重新排序”? -
没有。在你的例子中它不会发生
-
@Alex 一些解释会很好 - 为什么在这种情况下不会发生重新排序。最好有一些 JLS 链接。
-
我不认为应用程序程序员应该求助于 JSR-133 Cookbook,因为它只是一组关于 JVM 如何可能的建议 > 实施。甚至 HotSpot 也不总是遵循说明书,更不用说其他 JVM 实现了。语言规范应该是此类问题的唯一真实来源,如前所述,JMM 中没有任何内容可以阻止这种重新排序。
标签: java final java-memory-model instruction-reordering