gpt4 book ai didi

java - JVM 的隐式内存屏障在链接构造函数时如何表现?

转载 作者:搜寻专家 更新时间:2023-10-30 19:43:14 25 4
gpt4 key购买 nike

引用我的earlier question on incompletely constructed objects ,我有第二个问题。正如 Jon Skeet 指出的那样,在构造函数的末尾有一个隐式内存屏障,它确保 final 字段对所有线程都是可见的。但是,如果构造函数调用另一个构造函数怎么办?他们每个人的末尾都有这样的内存障碍,还是仅在首先被调用的那个的末尾有这样的内存障碍?也就是说,当“错误”的解决方案是:

public class ThisEscape {
public ThisEscape(EventSource source) {
source.registerListener(
new EventListener() {
public void onEvent(Event e) {
doSomething(e);
}
});
}
}

正确的应该是工厂方法版本:

public class SafeListener {
private final EventListener listener;

private SafeListener() {
listener = new EventListener() {
public void onEvent(Event e) {
doSomething(e);
}
}
}

public static SafeListener newInstance(EventSource source) {
SafeListener safe = new SafeListener();
source.registerListener(safe.listener);
return safe;
}
}

下面的方法是否也有效?

public class MyListener {
private final EventListener listener;

private MyListener() {
listener = new EventListener() {
public void onEvent(Event e) {
doSomething(e);
}
}
}

public MyListener(EventSource source) {
this();
source.register(listener);
}
}

更新: 基本问题是 this() 保证实际调用 上面的私有(private)构造函数(在这种情况下会有预期的屏障,一切都是安全的),或者私有(private)构造函数是否有可能内联到公共(public)构造函数中作为一种优化来保存一个内存屏障(在这种情况下不会有障碍,直到公共(public)构造函数结束)?

this() 的规则是否在某处精确定义?如果不是,那么我认为我们必须假设允许内联链接的构造函数,并且可能某些 JVM 甚至 javac 正在这样做。

最佳答案

我认为它是安全的,因为 java 内存模型指出:

Let o be an object, and c be a constructor for o in which a final field f is written. A freeze action on final field f of o takes place when c exits, either normally or abruptly. Note that if one constructor invokes another constructor, and the invoked constructor sets a final field, the freeze for the final field takes place at the end of the invoked constructor.

关于java - JVM 的隐式内存屏障在链接构造函数时如何表现?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2513841/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com