Friday, January 13, 2017

Better ways to implement Singleton in Java

Singleton Design pattern restrict creation of only once instance of a Class. That means inside a single JVM only one instance of the Singleton Class will be created.  In java we have broadly two options to implement Singleton.

1) Early Creation of the Object Instance.
2) Lazy Creation of the Object Instance: Here the instance is created on first invocation.

Following example demonstrate how to implement Singleton in Java.

Method 1: Early Creation of Object Instance
public class SingletonClass {
private static final SingletonClass INSTANCE = new SingletonClass(); //Private Constructor private SingletonClass() { //Do nothing } public static SingletonClass getInstance() { return INSTANCE; } }
Here the instance is created ahead even before calling the Class. We need to provide a private constructor otherwise Java Compiler will add a default Constructor.

Method 2: Lazy Creation of Object Instance
public class SingletonClass {
   private static volatile SingletonClass INSTANCE = null;
private SingletonClass() {
       //Do nothing
   }
public static SingletonClass getInstance() { if (INSTANCE == null) { synchronized (SingletonClass.class) { if (INSTANCE == null) { INSTANCE = new SingletonClass(); } } } return INSTANCE; } }
In Lazy creation apporach the instance of the Class will not be created unless the getInstance() method is called. The above implementation we are checking if the INSTANCE is null twice, once before the synchronized block and once after the block. This is known as  Double - Checked Locking. The volatile keyword here is very important and would work only in Java 5+.

Above examples one can still create multiple instances under the following conditions,
1) Cloning the Object from the Object returned by Singleton.
2) Serializing and Deserializing.
3) If multiple Class loader are used in an Application then each Class Loader can have multiple instance of the same object.

We can extend the above two example  to take care (1) and (2 )
by  prevent cloning(Implement Cloneable interface) and throw Exception from clone() method.
Serialization by implementing  (Serializable Interface) and implementing readResolve() method to return the instance.

Other simple and better option is using Java enum. If we use Enum then we do not have to take care of Clone or Serializable issues. JVM make sure enum instances are Singleton in a single Class Loader.



public enum SingletonClass {
  INSTANCE;
}
 //Which is equivalent to 
public final class SingletonClass { 
  public final static SingletonClass INSTANCE = new SingletonClass(); 
  }
}


No comments :

Post a Comment