I was reading the article Double-checked locking and the Singleton pattern, on how double checked locking is broken, and some related questions here on Stack Overflow.
I have used this pattern/idiom several times without any issues. Since I have been using Java 5, my first thought was that this has been rectified in Java 5 memory model. However the article says:
This article refers to the Java Memory Model before it was revised for Java 5.0; statements about memory ordering may no longer be correct. However, the double-checked locking idiom is still broken under the new memory model.
Is this a real problem, and, if so, under what conditions?
The start of a synchronization block guarantees that you see the latest data, but it does not guarantee reordering, you cannot expect a consistent view of data unless you are also in a synchronized block. It doesn't guarantee, that variables modifications done within synchronized section will be visible to other threads. Only the threads that enters the synchronized block is guaranteed to see the changes. This is the reason why double checked locking is broken - it is not synchronized on the reader's side. The reading thread may see, that the singleton is not null, but singleton data may not be fully initialized (visible).
On the other hand, ordering is provided by volatile which guarantees ordering, for instance write to volatile singleton static field guarantees that writes to the singleton object will be finished before the write to a volatile static field. It doesn't prevent creation singleton of two objects; this is provided by synchronize. Class final static fields doesn't need to be volatile. In Java, the JVM takes care of this problem.
More can be found in: