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:
volatile
write in one thread happens-before any subsequent volatile
read in another thread.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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With