If you’re a Java developer and you’re concerned about performance, you’ve probably encountered the (broken) double checked locking pattern (which I won’t reproduce here to make sure no one copies it accidentally. If you care, read the Wikipedia article).
Joshua Block has proposed a solution but there are a couple of fine points to it. If you don’t get it right, things are going to break in odd ways. So this should go into a helper class which handles all the boiler plate code. A post about final variables pointed me in the right direction. So without further ado, the LazyInit class:
/** Lazy initialization of a field value based on the (correct) * double checked locking idiom by Joschua Bloch * * <p>See "Effective Java, Second Edition", p. 283 */ public abstract class LazyInit<T> { private volatile T field; /** Return the value. * * <p>If the value is still <code>null</code>, the method will block and * invoke <code>computeValue()</code>. Calls from other threads will wait * until the call from the first thread will complete. */ public T get () { T result = field; if (result == null) // First check (no locking) { synchronized (this) { result = field; if (result == null) // Second check (with locking) { field = result = computeValue (); } } } return result; } protected abstract T computeValue (); /** Setter for tests */ public synchronized void set (T value) { field = value; } }
As an additional goodie, it allows you to override the value in tests. Here is how to use this code:
private LazyInit<String> field1 = new LazyInit<String> () { @Override protected String computeValue () { return "value"; } }; @Test public void testLazyInit () throws Exception { assertEquals ("value", field1.get ()); }
Simple, isn’t it?