Creating Thread-Safe Singleton?

posted 6 Feb 2012, 02:59 by Sanjeev Kumar   [ updated 16 Nov 2012, 10:45 ]

A singleton class should be designed to ensures that there exists only one instance per application. Special care must be taken if your application is deployed on a clustered environment as in this case it is possible that multiple instance of your singleton class are available in your application.  

Here are a few ways to create a thread safe singleton classes in your application.

1) Lazy loading Singleton instance - Using Synchronized method or block

public class SingletonClass{
    private SingletonClass sc;
    private SingletonClass(){}

    public static SingletonClass getInstance(){
        synchronized(SingletonClass.class) {
              if (sc == null) {
                  sc = new SingletonClass();
              } else {
                 return sc;
              }
        }
    }

}

Issues
- The use of synchronized keyword in a singleton class means that only one thread will be executing the synchronized block at a time and all other threads would be waiting.

2) Early initialization Singleton - Using Static Member Variable

public class SingletonClass{
    private static sc = new SingletonClass();
    private SingletonClass(){}

    public static SingletonClass getInstance(){
        return sc;
    }
}

This approach is also known as early initialization because we are creating the singleton instance at an early stage and not when the instance is actually needed by another class.

Issues
- The use of static member variable means that this singleton instance will be created as soon as the class is loaded by any Classloader in JVM. 

3) Singleton using Inner Classes

public class SingletonClass{
    private SingletonClass(){}
    private static class InstanceHolder{
        private static final SingletonClass INSTANCE = new SingletonClass();
    }
    public static SingletonClass getInstance(){
        return InstanceHolder.INSTANCE; //line1
    }
}

Here the instance is being created on demand and is also thread safe. The use of inner classes helps in the sense that the very first time singleton object is requested, the inner class is loaded by line1 and this loading of inner class causes the static member variable to be created and returned. Next time, the singleton member variable is requested causes the same static reference variable to be returned.

4) Singleton using enums

public enum Singleton{
    INSTANCE;
    private int a;
    public int getA() {
        return a;
    }
}

To get a single instance of this enum one should use:
Singleton.INSTANCE
To get the value of member variable a, one should use:
Singleton.INSTANCE.getA();

In my experience using enums is the best way to implement Singleton design pattern in any Java application. It is thread safe and also provides lazy initialization.
Comments