参考类型的易失性 - 它总是避免由于JMM发布参考问题? [英] Volatile for reference type - Does it always avoid publication of references issues due to JMM?

查看:127
本文介绍了参考类型的易失性 - 它总是避免由于JMM发布参考问题?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设这个类:

  public class AmIThreadSafe {

private int a;
private int b;

AmIThreadSafe(int a,int b){
this.a = a;
this.b = b;
}
}

假设实例引用此类(声明为< (引用)转义时,某些线程可以访问(导致竞争条件):code> volatile p>

  volatile AmIThreadSafe instance = new AmIThreadSafe(1,2); 

在这里,我确定分配实例

但是关于 AmIThreadSafe的 c> fields?



外部 volatile 关键字也意味着发生之前关系 a b 字段?
或者是可能的任何线程看到过时的值(默认值 0 在这种情况下,因为 int



换句话说,我应该声明 a b final volatile 或者只是在实例的引用上指示 volatile



< ----- 更新后 - 好的答案: ----------------------------



以下文章通过其样例证实了在我的情况下, a b 受到JMM优化的保护,防止永久 发生之前 关系。



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

解决方案

实例声明为 volatile 不会使其字段 volatile ,但如果我正确理解你的问题,然后—是的,在你的情况下就够了。



§ 17.4.5的规范




  • a volatile 写入一个线程 happens-before 任何后续 volatile 线程。

  • 同一个线程中的语句具有您期望的 happens-before 关系。

  • > 关系是可传递的。



因此,如果线程感知到 code>作为已经初始化,然后实例 发生之前的的初始化,以及实例的字段 happens-before ,因此线程会将实例的字段视为已初始化。


Assuming this class:

public class AmIThreadSafe {

    private int a;
    private int b;

    AmIThreadSafe(int a, int b) {
        this.a = a;
        this.b = b;
    }
}

Assuming that instance's reference to this class (declared as volatile) is accessible by some threads (leading to race condition) as soon as the this(reference) escapes:

volatile AmIThreadSafe instance = new AmIThreadSafe(1,2);

Here, I'm sure that the fact of assigning instance reference happens-before reading by threads.

But what about the AmIThreadSafe's fields?

Does the external volatile keyword also imply an happens-before relation concerning a and b fields? Or is it rather possible to end up with any thread seeing stale values (default values 0 in this case since int) due to a potential statements reordering during constructor?

In other word, should I declare a and b final or volatile to prevent any surprises with the JMM or is just indicating volatile on the instance's reference enough?

----------------UPDATED POST - A GOOD ANSWER:----------------------------

The following article confirms by its sample that in my case, a and b are protected from JMM optimisations that prevent a permanent happens-before relation.

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

解决方案

Declaring instance as volatile does not make its fields volatile, but if I understand your question correctly, then — yes, it's enough in your case.

Per §17.4.5 of the spec:

  • a volatile write in one thread happens-before any subsequent volatile read in another thread.
  • statements within the same thread have the happens-before relationship that you'd expect.
  • happens-before relationships are transitive.

So, if a thread perceives instance as having been initialized, then the initialization of instance happened-before it, and the initialization of instance's fields happened-before that, so the thread will perceive instance's fields as having been initialized.

这篇关于参考类型的易失性 - 它总是避免由于JMM发布参考问题?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆