Lazy Initialization, Singleton Pattern and Double Checked locking

Lazy Initialization

Lazy Initialization is a technique where one postpones the instantiation of a object until its first use. In other words the instance of a class is created when its required to be used for the first time. The idea behind this is to avoid unnecessary instance creation. But there are concerns related to using such approaches in a concurrent scenario. But before that lets see how lazy initialization looks:

When the above code is executed in a multi threaded program the concern that immediately comes to the mind is the “Race condition”. Thread A would check that resource == null so it goes inside to create the instance but might go into Runnable status before it creates the Resource instance. Thread B also checks that resource == null and it goes ahead, creates the instance and uses it for its operations. Thread A comes back to running status and it also continues to create its own instance and start using it.

Now in the above case suppose we wanted both Thread A and Thread B to work on the same instance, but due to the race condition they would work on different instances. If the Resource instances has state information associated with it then it because a critical problem. Lets stop here and then see how Singleton is related to this.

Singleton

Singleton is one of the Creational Design Patterns discussed in the GoF Design Patterns. The main idea behind the Singleton pattern is to control the creation of objects for a given class such that at any time there’s only one instance of that particular class. So lets see how we can implement the Singleton pattern:

where in the above example Resource is a singleton. This is very similar to the concept of lazy initialization and this as well suffers from the issues seen while using this is a multi threaded environment/program.

Double Checked Locking

One way to solve the problem with Lazy initialization and singleton in a multi threaded program is to declare the getInstance() or getResource() method as synchronized. But its a huge overhead because everytime the method is invoked it has to go through the process of waiting for the lock and then obtaining the lock and its unnecessary because its only once that the instance is created and all subsequent invocations would just return that instance.

To work around this issue, Double Checked Locking is the pattern used. In this approach the methods are not synchronized instead the instance creation code is put in a synchronized block. Let me show an example:

In the above code there are two null checks- one outside the synchronized block and one within it. The synchronized block is executed at most once and any other thread trying to get instance would have to wait until the instantiation to complete.

The above approach also has some issues. The initialization of an object and the creation of instance of that class are 2 different operations. Once the instance of the class has been created that instance is then used to initialize the values of its state either with default values or some user defined values. Now between these 2 operations another thread might invoke the method to get the instance and sees that the instance is already not null and then proceeds with using that instance. Though its the correct instance we wanted the thread to use but that instance hasn’t been initialized yet. This issue is called as Unsafe Publication. Java Concurrency in Practice book has a really good chapter on Java Memory Model and issues related to Safe Publication and Unsafe Publication of instances.

Lazy Initialization holder class idiom

One can read about this Lazy Initialization holder class Idiom in the interview with Joshua Bloch here. It has been covered in Effective Java by Joshua Bloch and also in Java Concurrency in Practice. Let me just share that idea here: