使字段"volatile"会阻止并发情况下的所有内存可见性问题吗?

Bha*_*kar 6 java concurrency memory-model

制作类字段是否会在并发情况下volatile阻止所有内存可见性问题?是否有可能对于下面的类,获取Test对象引用的线程x首先看到0(默认值为int)然后是10?我认为这是可能的,当且仅当构造函数在没有完成(不正确的发布)的情况下Test放弃this引用.有人可以验证/纠正我吗?

class Test {
    volatile int x = 10;            
}
Run Code Online (Sandbox Code Playgroud)

第二个问题:如果是这样的话final int x=10;

Joh*_*int 6

根据JMM,您实际上无法保证看到x = 10.

例如,如果你有

Test test =  null;

Thread 1 -> test = new Test();
Thread 2 -> test.x  == // even though test != null, x can be seen as 0 if the
                       // write of x hasn't yet occur
Run Code Online (Sandbox Code Playgroud)

现在,如果你有

class Test{
  int y = 3;
  volatile x = 10;
}
Run Code Online (Sandbox Code Playgroud)

如果thread-2读取x == 10 thread-2保证读取y == 3

回答你的第二个问题.

拥有final字段将在构造函数之后和发布之前发出storestore,因此具有final final字段实际上将确保您看到x = 10.

编辑:正如yshavit所说.你失去了我在第一个例子中提到的带有最终字段的发生之前的关系,就像yshavit把它放在线程2读取x == 10它可能不读取y == 3其中x是最终字段.