By reading Java Concurrency in Practice
I can see:
To publish an object safely, both the reference to the object and the object's state must be made visible to other threads at the same time. A properly constructed object can be safely published by:
- Initializing an object reference from a static initializer
- Storing a reference to it into a volatile field or AtomicReference
- Storing a reference to it into a final field of a properly constructed object
- Storing a reference to it into a field that is properly guarded by a lock.
However, I am confused about the second idiom. Since volatile
can only guarantee that the reference is visible to another thread but it doesn't have synchronization of object construction which it refers to. So how can it guarantee that the mutable object is properly constructed, what is the thread that is constructing this object is interrupted by another thread?
We need to show that constructing an object and assigning it to a volatile variable happens before it is read from that variable.
From JLS Chapter 17:
So, construction of an object happens before it is assigned to a volatile variable, from the point of view of that thread.
And:
If we could show that writing the volatile variable (action y) synchronizes-with reading the variable (action z), we could use the transitivity of happens-before to show that constructing the object (action x) happens-before reading the object. Luckily:
Therefore, we can see that a properly constructed object is visible to any thread when published this way.
Reads and writes are atomic for all variables declared
volatile
(includinglong
anddouble
variables).Consequence:
volatile
guarantees, among others, that the variable is always read from the memory shared by all threads - if the value is published in avolatile
variable, it must be fully constructed before.In other words, if a
volatile
value is not published, then no other threads will know about it - most probably the result of 'construction in progress' may reside in the CPU cache or in the memory that JVM uses as "space I'm using for my own purposes; you puny Java code, don't ask what's in it, it's not your business".Yes. You are right. You can find more details of internals about volatile variables in below question:
Difference between volatile and synchronized in Java
You have to use other programming constructs for thread safety : Using
synchronized
constructs or alternatives ofsynchronized
constructs.Refer to below related SE question:
Avoid synchronized(this) in Java?