【发布时间】:2017-08-24 09:23:24
【问题描述】:
我遇到了以下代码in an article somewhere on the Internet:
public class MyInt {
private int x;
public MyInt(int y) {
this.x = y;
}
public int getValue() {
return this.x;
}
}
文章指出
编译器(JIT、CPU 等)不会对构造函数进行特殊处理,因此允许对来自构造函数的指令和构造函数之后的指令重新排序。
另外,this JSR-133 article 关于 Java 内存模型指出
只有在对象完全初始化后才能看到对该对象的引用的线程,可以保证看到该对象的最终字段的正确初始化值。
上面提到的MyInt 实例似乎是不可变的(除了该类没有标记final)并且是线程安全的,但文章指出它不是。他们声明不能保证x 在读取时始终具有正确的值。
但我认为
只有创建对象的线程才能在构造对象时访问它
Java Tutorials 似乎非常支持这一点。
我的问题是:这是否意味着,对于当前的 JMM,由于指令重新排序,线程可以访问部分构造的对象?如果是,如何?这是否意味着 Java 教程中的陈述根本不正确?
【问题讨论】:
-
另一个线程如何引用一个其构造函数尚未完成执行的对象?
-
@daniu 这也是我想知道的事情,因此我很困惑。
标签: java concurrency final java-memory-model