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