构造函数和指令重新排序
我刚刚遇到了一篇文章,它提出了一个我以前从未听说过的主张,在其他任何地方都找不到。该声明是,从另一个线程的角度来看,构造函数返回的值的赋值可以相对于构造函数内部的指令重新排序。换句话说,声明是在下面的代码中,另一个线程可以读取尚未设置值 的非 null 值。a
x
class MyInt {
private int x;
public MyInt(int value) {
x = value;
}
public int getValue() {
return x;
}
}
MyInt a = new MyInt(42);
这是真的吗?
编辑:
我认为可以保证,从线程执行的角度来看,的赋值与 的赋值具有发生之前的关系。但是这两个值都可能缓存在寄存器中,并且它们可能不会以最初写入的相同顺序刷新到主存储器中。因此,如果没有内存屏障,另一个线程可以在写入 的值之前读取 的值。正确?MyInt a = new MyInt(42)
x
a
a
x
因此,根据axtaftt的回答和随后的评论,这些对线程安全性的评估是否正确?
// thread-safe
class Foo() {
final int[] x;
public Foo() {
int[] tmp = new int[1];
tmp[0] = 42;
x = tmp; // memory barrier here
}
}
// not thread-safe
class Bar() {
final int[] x = new int[1]; // memory barrier here
public Bar() {
x[0] = 42; // assignment may not be seen by other threads
}
}
如果这是正确的...哇,这真的很微妙。