Tuesday, September 7, 2010

Lazy initialization of Java Singletons

Code snippet below shows a typical way of initializing singleton class in Java.

class Singleton {
  private static Singleton singleton;

  private Singleton() {
  }

  public static synchronized Singleton getSingleton() {
      if (singleton == null)
          singleton = new Singleton();
      return singleton;
  }
}


Nothing wrong with this approach but the only issue is performance penalty we pay for the synchronized block. Another not so clean way to get around this is by using Double-checked locking idiom as shown below in the code snippet. But again volatile variables are not terribly fast as compared to synchronized blocks so the performance mileage we get out this, won't be much.

class Singleton {
  private volatile static Singleton singleton;

  private Singleton() {
  }

  public static Singleton getSingleton() {
      if (singleton == null) {
          synchronized (Singleton.class) {
              if (singleton == null)
                  singleton = new Singleton();
          }
      }
      return singleton;
  }
}

Fortunately, there is a better and cleaner way of doing this by using Initialization on Demand Holder Idiom.
...
static class SingletonHolder {
  private static Singleton singleton = new Singleton();

  public static Singleton getSingleton() {
      return singleton;
  }
}
...

The trick here is that whenever the first call to SingletonHolder.getSingleton() is made, the SingletonHolder static class will be loaded into the JVM and so, JVM will take care of synchronizing if multiple threads are invoking the method and hence it is obviously going to be more efficient than users doing synchronization.