参考类型的易失性 - 它总是避免由于JMM发布参考问题? [英] Volatile for reference type - Does it always avoid publication of references issues due to 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 $> 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
,但如果我正确理解你的问题,然后—是的,在你的情况下就够了。
- 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 subsequentvolatile
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屋!