Java – volatility of reference types – does it always avoid publishing references due to JMM?
Suppose this lesson:
public class AmIThreadSafe { private int a; private int b; AmIThreadSafe(int a,int b) { this.a = a; this.b = b; } }
Suppose that the instance's reference to this class (declared volatile) can be accessed by some threads (leading to a race condition), as long as this (Reference) escape:
volatile AmIThreadSafe instance = new AmIThreadSafe(1,2);
Here, I'm sure that the fact of allocating instance references occurs before the thread reads
But what about amithreadsafe?
Does the external volatile keyword also mean a prior relationship about the A and B fields? Or is it possible to eventually get any thread to see stale values due to potential statements reordered in the constructor (in this case, the default value since int is 0)?
In other words, should I declare a and B final or volatile to prevent any accidents from JMM, or just indicate volatile on the instance reference?
————- - updated post - a good answer: - - - - - -
The following article confirms through its samples that in my case, a and B are protected from JMM optimizations, which can prevent the permanent occurrence of previous relationships
http://jeremymanson.blogspot.fr/2008/11/what-volatile-means-in-java.html
Solution
Declaring an instance volatile doesn't make its fields unstable, but if I understand your problem correctly – yes, it's enough in your case
Per § 17.4 5 of the spec:
>Volatile writes in one thread occur before any subsequent volatile reads in another thread. > Statements in the same thread have the relationship you expect to happen before. > Occurs before the relationship is passed
Therefore, if a thread regards an instance as initialized, the initialization of the instance occurs before it, and the initialization of the field of the instance occurs before it. Therefore, the thread will perceive that the field of the instance has been initialized