Robert Schonberger at thought home

Feb 10 2009

So for a little while now, i’ve been encouraging people in the team to always use Double Checked Locking in java. Whats that you may ask? Well, in Java, getting a synchronized lock on things can be slow. A lot of code, including code in java.util.* has points like this:

 1 private Object expensive;
 3 public Object getSomething() {
 4   synchronized {
 5     if (expensive) {
 6       expensive = new Object(); 
 7     }
 8   }
 9   return expensive;
10 }

The problem here is that you always try to get the lock. The nicer idiom, that is called Double Checked Locking is:

 1 public Object getSomething() {
 2   if (null == expensive) {
 3     synchronized {
 4       if (null == expensive) {
 5         expensive = new Object(); 
 6       }
 7     }
 8   }
 9   return expensive;
10 }

This results in a way to only get the lock, and it looks hunky dory. Well almost. Java has a memory model that allows the situation to get muddled, whereby if two different threads are running, and the JVM decides that some optimizations are better, the JVM is free to set the object reference on Object expensive before the constructor has been fully called. Oops! Thats can be a disaster.

So what are you supposed to do? Well, there are several idioms, but essentially, the problem is that the JVM has decided to optimise this beyond what it should. If you use Java >= 1.5 and use the volatile keyword, you can be guaranteed that the field is a barrier – and that you’ll get it fully initialized; That is, in Java 1.5 and above, you can do the following to be safe:

 1 private volatile Object expensive;
 3 public Object getSomething() {
 4   if (null == expensive) {
 5     synchronized {
 6       if (null == expensive) {
 7         expensive = new Object(); 
 8       }
 9     }
10   }
11   return expensive;
12 }

And be done with it. A slightly more thorough “Double Checked Locking” Is Broken article describes the problem in full, with a delve into depths ot the JVM memory model.

Alternatively, Wikipedia to the rescue provides several examples of different ways of instantiating singletons in Java and other languages in the Singleton Pattern article.

blog comments powered by Disqus