Archive for Java

Singleton Pattern Caveats in Java

The singleton design pattern arguably the simplest pattern to implement. Unfortunately there are some caveats when implementing it in Java. To recap, GoF defines the singleton as follows:

“Ensure a class only has one instance, and provide a global point of access to it.”

A simple Java implementation of the singleton design pattern is:


public class Singleton {
   private static Singleton mInstance;

   private Singleton() {}

   public Singleton getInstance() {
      if (mInstance == null)                // Step 1
         mInstance = new Singleton();  // Step 2

      return mInstance;
   }
}

The main caveat is that the above implementation is not thread safe. Imagine the Singleton instance is not initialized and two threads call getInstance() at the same time:

  1. Thread 1 reaches step 1, checks that mInstance is null and proceeds to step 2.
  2. Thread 1 is preempted by thread 2 before mInstance is instantiated by thread 1.
  3. Thread 2 reaches step 1, checks that mInstance is null and proceeds to step 2.
  4. Thread 2 is preempted by thread 1.
  5. Thread 1 initializes mInstance and returns it.
  6. Thread 1 is preempted by thread 2.
  7. Thread 2 instantiates a new instance of Singleton, assigns it to mInstance and returns it.

Now, there are two instances of the Singleton class which violates the definition of a Singleton: “Ensure a class only has one instance.” The easy solution is to synchronize the getInstance() method:


public class Singleton {
   private static Singleton mInstance;

   private Singleton() {}

   public synchronized Singleton getInstance() {

      if (mInstance == null)                  // Step 1
         mInstance = new Singleton();    // Step 2

      return mInstance;
   }
}

Synchronizing the getInstance() method is not desirable because synchronization is expensive and the getInstance() method only needs to be synchronized the first time it’s called.

My favorite design patterns book, Head First Design Patterns, identifies this problem and suggests the following solution:


public class Singleton {
   private static volatile Singleton mInstance;

   private Singleton() {}

   public Singleton getInstance() {
      if (mInstance == null) {
         synchronized (Singleton.class) {
            if (mInstance == null)
               mInstance = new Singleton();
         }
      }

      return mInstance;
   }
}

The above technique is called “double-checked locking” and ensures that synchronization is only used the first time a singleton is initialized. Note that this technique only works in Java 1.5 and above because the volitile keyword has been fixed: see this article for more details. The article also points out that using the volitile keyword does not provide much of a performance boost over synchronizing the getInstance() method so the following solution is recommended:


public class Singleton {

   private Singleton() {}

   private static class SingletonHolder {
      private static final Singleton INSTANCE = new Singleton();
   }

   public Singleton getInstance() {
      return SingletonHolder.INSTANCE;
   }
}

The above solution is thread safe and offers lazy initialization. It is thread safe because the Singleton instance is initialized when the SingletonHolder class’s static initializer is run. Static initializers are run when the class is initialized. The java language specification guarantees class initialization to be synchronized (see JLS 12.4.2). The solution offers lazy initialization because the SingletonHolder class is not initialized until it is referenced by the getInstance() method (see JLS 12.4.1).

Comments