Saturday, April 16, 2016

Java Singleton

Java singleton class is per classloader.
Java Singleton Rules for implementing the singleton classes, but the class should be instantiated only once 
per classloader. Here is the basic steps for implementing the Java Singleton class.

a) When you say singleton class, there should be only one instance of that class can be created.
b) Constructor of that class has to be made as private to avoid instantiation from external classes.
c) Declare a static variable to store the instance for that class.
d) Declare a method that returns the instance of that class.
With the above basic rules, one can classify Java Singleton implementation into the following categories:

1) Eager Initialization
2) Static Block Initialization
3) Lazy Initialization
4) Thread Safe Singleton

Eager Initialization

In eager initialization, the singleton instance is created at the time of loading class loading. This is 
the easiest way to create the singleton instance for your singleton class. But, the main drawback of this
approach is that the instance will be created even though it is not used by any of the client application.
In this approach, you have to just create instance in the static variable declaration.  This approach 
doesn’t provide any option for exception handling.

Here is the example for eager initialization of singleton instance:

public class EagerInitialization {
    private static final EagerInitialization instance = new EagerInitialization();
    private EagerInitialization(){}
    public static EagerInitialization getInstance(){
        return instance;
    }
}

Static Block Initialization

This also falls under the eager initialization, the only difference is that instance creation is completed 
inside the static initializer block.  This approach doesn’t provide any option for exception handling.

Here is the example for static block initialization of singleton instance:

public class StaticBlockInitialization { 
    private static StaticBlockInitialization singletonInstance;     
    private StaticBlockInitialization(){}     
    static{
        try{
            singletonInstance = new StaticBlockInitialization();
        }catch(Exception e){
            throw new RuntimeException("Exception occured while creating the singleton instance");
        }
    }     
    public static StaticBlockInitialization getInstance(){
        return singletonInstance;
    }
}

Lazy Initialization

In this approach, we are creating the instance only after loading the class and first invocation of the
instance. This will avoid pre-initializing the instance where you don’t need the instance it is requested
by the service.

This approach works fine when this class is executed in the single threaded environment, but this will not
work fine in the multi-threaded environment when multiple threads are trying to get the new instance 
simultaneously 

Here is the simple example for Java Singleton class using lazy initialization approach:

class Singleton {
 private Singleton() {}
 private static Singleton singleton;
 private int value = 1;
 public static Singleton getInstance() {
  if (singleton == null) {
   singleton = new Singleton();
  }
  return singleton;
 }
 public int getValue() {
  return value;
 }
 public void setValue(int value) {
  this.value = value;
 } 
}

public class Main {
 public static void main(String args[]) {
  Singleton singleton = Singleton.getInstance();
  System.out.println("Value 1 : " + singleton.getValue());
  singleton.setValue(2);
  Singleton singleton2 = Singleton.getInstance();
  System.out.println("Value 2: " + singleton2.getValue());
 }
}

Thread Safe Singleton

This is similar to the above approach except that the method used for creating the singleton instance 
is synchronized.This approach is the most safest and best solution to implement the singleton instance, 
but it has the performance issues when multiple threads to trying to access the instance simultaneously.
Here is the example for thread safe singleton instance:

public class ThreadSafeInstance { 
    private static ThreadSafeInstance singletonInstance;
    private ThreadSafeInstance(){}
    public static synchronized ThreadSafeInstance getInstance(){
        if(singletonInstance == null){
            singletonInstance = new ThreadSafeInstance();
        }
        return singletonInstance;
    }
}

No comments:

Post a Comment