This question already has an answer here:
private volatile static Singleton uniqueInstance
In a singleton when using double lock method for synchronization why is the single instance declared as volatile ? Can I achieve the same functionality without declaring it as volatile ?
Without
volatile
the code doesn't work correctly with multiple threads.From Wikipedia's Double-checked locking:
In general you should avoid double-check locking if possible, as it is difficult to get right and if you get it wrong it can be difficult to find the error. Try this simpler approach instead:
Write to a volatile field will happen before any read operation. Below is an example code for better understanding:
This link can serve you better http://javarevisited.blogspot.com/2011/06/volatile-keyword-java-example-tutorial.html
To avoid using double locking, or volatile I use the follow
Creating the instance is simple, lazy loaded and thread safe.
The
volatile
prevents memory writes from being re-ordered, making it impossible for other threads to read uninitialized fields of your singleton through the singleton's pointer.Consider this situation: thread A discovers that
uniqueInstance == null
, locks, confirms that it's stillnull
, and calls singleton's constructor. The constructor makes a write into memberXYZ
inside Singleton, and returns. Thread A now writes the reference to the newly created singleton intouniqueInstance
, and gets ready to release its lock.Just as thread A gets ready to release its lock, thread B comes along, and discovers that
uniqueInstance
is notnull
. ThreadB
accessesuniqueInstance.XYZ
thinking that it has been initialized, but because the CPU has reordered writes, the data that thread A has written intoXYZ
has not been made visible to thread B. Therefore, thread B sees an incorrect value insideXYZ
, which is wrong.When you mark
uniqueInstance
volatile, a memory barrier is inserted. All writes initiated prior to that ofuniqueInstance
will be completed before theuniqueInstance
is modified, preventing the reordering situation described above.You can use the follow code: