是否保证易失性字段被正确初始化

Hli*_*lib 6 java volatile java.util.concurrent java-memory-model

这里

当对象的构造函数完成时,该对象被认为已完全初始化。仅在对象完全初始化后才能看到对该对象的引用的线程保证看到该对象的最终字段的正确初始化值。

现场是否有同样的保证volatile?如果y下面的例子中的字段是volatile我们可以观察到的呢0

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
    } 
} 
Run Code Online (Sandbox Code Playgroud)

}

小智 5

0是的,什么时候可以看到

\n
class FinalFieldExample { \n  final int x;\n  volatile int y;\n  static FinalFieldExample f;\n  ...\n}\n
Run Code Online (Sandbox Code Playgroud)\n

简短的解释:

\n
    \n
  • writer()f = new FinalFieldExample()线程通过数据竞争发布对象
  • \n
  • 由于这种数据竞争,reader()线程可以将f = new FinalFieldExample()对象视为半初始化。
    \n特别是,线程可以看到 \xe2\x80\x94之前reader()的值,即初始值。yy = 4;0
  • \n
\n

更详细的解释在这里

\n

您可以使用jcstress 测试在 ARM64 上重现此行为。

\n