参考类型的易失性 - 是否始终避免因JMM而发布引用问题?

Mik*_*378 7 java concurrency multithreading volatile thread-safety

假设这堂课:

public class AmIThreadSafe {

    private int a;
    private int b;

    AmIThreadSafe(int a, int b) {
        this.a = a;
        this.b = b;
    }
}
Run Code Online (Sandbox Code Playgroud)

假设volatile一旦this(引用)转义,某个线程可以访问实例对此类的引用(声明为)(导致竞争条件):

volatile AmIThreadSafe instance = new AmIThreadSafe(1,2);
Run Code Online (Sandbox Code Playgroud)

在这里,我确信分配instance引用的事实发生在线程读取之前.

但那些AmIThreadSafe's领域呢?

外部volatile关键字是否也暗示happens-before关系ab字段?或者由于在构造函数中重新排序的潜在语句,是否有可能最终看到任何线程看到陈旧值(0在本例中为默认值int)?

换句话说,我应该声明a和/ b finalvolatile防止JMM出现任何意外,或者只是volatile在实例的参考上做出足够的指示?

---------------- 更新的帖子 - 一个好的答案: --------------------------- -

以下文章通过其样本确认,在我的情况下,a并且b受到JMM优化的保护,这些优化可以防止永久发生之前的关系.

http://jeremymanson.blogspot.fr/2008/11/what-volatile-means-in-java.html

rua*_*akh 4

声明instanceasvolatile不会使其 fields volatile,但如果我正确理解你的问题,那么 - 是的,对于你的情况来说就足够了。

根据规范的 §17.4.5

  • volatile一个线程中的写入发生另一线程中的任何后续volatile读取之前。
  • 同一线程中的语句具有您期望的先发生关系。
  • 发生之前关系是可传递的。

因此,如果一个线程感知instance到已经被初始化,那么 的初始化instance 发生在它之前instance,并且的字段的初始化发生在它之前,因此线程将感知到instance的字段已经被初始化。