Hi guys lets
discuss about Singleton pattern.
Singleton
pattern is a creational pattern, where there will be a single instance for
Singleton class across the application.
To create a
Singleton class we need to follow following step.
1) Declare constructor as private to
restrict class instantiation.
2) Private static variable of the
class.
3) Public static method that returns
the instance of the class.
Singleton
pattern implementation –
1)
Eager initialization
In eager initialization, the instance of Singleton Class is created at
the time of class loading, it has a drawback that instance is created even
though client application might not be using it.
public class SingletonWithEagerInitialized {
private static final
SingletonWithEagerInitialized instance = new SingletonWithEagerInitialized();
private
SingletonWithEagerInitialized() {
}
public static
SingletonWithEagerInitialized getInstance() {
return instance;
}
}
2)
Static block initialization
Static block initialization implementation is similar to eager
initialization, except that instance of class is created in the static block
that provides option for exception handling.
class SingletonWithStaticBlock {
private static SingletonWithStaticBlock
instance;
private
SingletonWithStaticBlock() {
}
static {
try {
instance = new
SingletonWithStaticBlock();
} catch (Exception e) {
throw new RuntimeException("Exception
occured in creating singleton instance");
}
}
public static
SingletonWithStaticBlock getInstance() {
return instance;
}
}
3)
Lazy Initialization
Lazy initialization method to implement Singleton pattern creates the
instance in the global access method. Here is the sample code for creating
Singleton class with this approach.
class SingletonWithLazyInitialized {
private static
SingletonWithLazyInitialized instance;
private
SingletonWithLazyInitialized(){}
public static
SingletonWithLazyInitialized getInstance(){
if(instance == null){
instance = new
SingletonWithLazyInitialized();
}
return instance;
}
}
4)
Thread Safe Singleton
The easier way to create a thread-safe singleton class is to make the
global access method synchronized, so that only one thread can execute this
method at a time. General implementation of this approach is like the below
class.
class SingletonThreadSafe {
private static SingletonThreadSafe instance;
private
SingletonThreadSafe() {
}
public static SingletonThreadSafe
getInstanceUsingDoubleLocking() {
if (instance == null) {
synchronized
(SingletonThreadSafe.class) {
if (instance == null) {
instance = new
SingletonThreadSafe();
}
}
}
return instance;
}
}
5)
Bill Pugh Singleton
Implementation
Prior to Java 5, java memory model had a lot of issues and above
approaches used to fail in certain scenarios where too many threads try to get
the instance of the Singleton class simultaneously. So Bill Pugh came up with a
different approach to create the Singleton class using an inner static helper
class. The Bill Pugh Singleton implementation goes like this;
class SingletonBillPugh {
private
SingletonBillPugh(){}
private static class SingletonHelper{
private static final SingletonBillPugh INSTANCE = new SingletonBillPugh();
}
public static SingletonBillPugh
getInstance(){
return SingletonHelper.INSTANCE;
}
}
6)
Using Reflection to destroy
Singleton Pattern
Reflection can be used to destroy all the above singleton implementation
approaches
class ReflectionSingletonTest {
public static void main(String[] args) {
SingletonWithEagerInitialized instanceOne = SingletonWithEagerInitialized.getInstance();
SingletonWithEagerInitialized instanceTwo = null;
try {
Constructor[]
constructors =
SingletonWithEagerInitialized.class.getDeclaredConstructors();
for (Constructor constructor : constructors) {
//Below code will
destroy the singleton pattern
constructor.setAccessible(true);
instanceTwo
= (SingletonWithEagerInitialized) constructor.newInstance();
break;
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(instanceOne.hashCode());
System.out.println(instanceTwo.hashCode());
}
}
7)
Enum Singleton
To overcome this situation with Reflection, Joshua Bloch suggests the use
of Enum to implement Singleton design pattern as Java ensures that any enum
value is instantiated only once in a Java program. Since Java Enum values are
globally accessible, so is the singleton. The drawback is that the enum type is
somewhat inflexible; for example, it does not allow lazy initialization.
enum EnumSingleton {
INSTANCE;
}
8)
Serialization and Singleton
The problem with above serialized singleton class is that whenever we
deserialize it, it will create a new instance of the class. To overcome this scenario all we need to do it
provide the implementation of readResolve() method.
protected Object readResolve() {
return getInstance();
}