在多线程环境中读取的值 [英] Values read in Multithreading environment
问题描述
我正在阅读有关线程和锁的 JLS 文档http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.5.
I was going through the JLS documentation on Thread and Locks http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.5 .
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
}
}
}
我对本节中提到的关于如何将 f.y 视为零的上述示例(ex no 17.5-1)感到困惑.读取器线程要么将对象 f 读取为 null,在这种情况下它不会执行任何操作,要么将读取带有某个引用的对象 f.如果对象 f 有一个引用,那么即使多个写入线程正在运行,构造函数也必须完成它的执行,以便可以将引用分配给 f,如果构造函数已经执行,那么 f.y 应该被视为 4.
I am confused with above example (ex no 17.5-1) mentioned in the section as to how f.y could be seen as zero. The Reader Threads will either read the object f as null in which case it will not execute anything or it will read the object f with some reference. If the object f has a reference then the constructor must have completed its execution even though Multiple Writer Threads are running so that a reference could be assigned to f and if the constructor has executed then f.y should be seen as 4.
f.y =0 在什么条件下可能?
In what condition can f.y =0 be possible?
谢谢
推荐答案
f.y =0 在什么条件下可能?
In what condition can f.y =0 be possible?
Java 内存模型允许 JIT 编译器重新排列构造函数外部非最终字段的初始化顺序.x
字段是最终的,所以它必须由 JVM 初始化,但 y
不是最终的.因此,有可能 FinalFieldExample
已分配并设置在 static FinalFieldExample f
上,但 y
字段的初始化尚未完成.
The Java memory model allows the JIT compiler to reorder initialization of non final fields outside the constructor. The x
field is final so it must be initialized by the JVM but y
is not final. So there is the possibility that the FinalFieldExample
is allocated and set on static FinalFieldExample f
but the initialization of the y
field has not been completed.
引用 17.5-1:
因为 writer 方法在对象的构造函数完成后写入 f,所以 reader 方法将保证看到 f.x 的正确初始化值:它将读取值 3.但是,f.y 不是 final;因此,读者方法不能保证看到它的值 4.
Because the writer method writes f after the object's constructor finishes, the reader method will be guaranteed to see the properly initialized value for f.x: it will read the value 3. However, f.y is not final; the reader method is therefore not guaranteed to see the value 4 for it.
因为 f.y
不是最终的,所以不能保证在构造函数完成和分配 static f
时它已经被设置.因此,创建了一个竞争条件,并且 reader
可能会看到 y
为 3 或 0,具体取决于这个竞争.
Because f.y
is not final there is no guarantee that it has been set by the time the constructor finishes and the static f
is assigned. So there is a race condition created and the reader
may see y
as 3 or 0 depending on this race.
这篇关于在多线程环境中读取的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!