Wednesday, January 13, 2010

Singleton pattern

Implies having at most single instance of a class.

Need:Singleton provides global way to access resources. Suppose we have a centralize configuration data to be used across the application, more than one instance of configuration data will result in incorrect behaviour of application. There are other examples as well when we need singleton mainly, thread pools, caches etc.

Ways to create:

class IAmSingleton{

private static IAmSingleton singletonRef;
public static IAmSingleton getInstance(){
if(singletonRef ==null)
return singletonRef = new IAmSingleton(); //line 1
else
return singletonRef ;
}
private IAmSingleton(){}
}

What if two threads are at line 1, two instances will be created. To stop this lets syncronize getInstance().
Synchronization come with cost of performance loss. Lets see how can we achieve single instance in multi threading environment with less impact.

If the object desired to behave as singleton is less resource incentive, we can go for pre loading the class(instance of class will be created at the class loading time).

class IAmSingleton{
private static IAmSingleton singletonRef = new IAmSingleton();
private IAmSingleton(){}
}

But if its resource incentive we can try to improve our synchronization logic. Lets see how..

class IAmSingleton{

private static volatile IAmSingleton singletonRef ;
public static IAmSingleton getInstance(){
if (singletonRef ==nulll)
syncronize (IAmSingleton.class){
if (singletonRef == null)
return new IAmSingleton();
else
return singletonRef ;
}
}
else
return singletonRef ;
}
privateIAmSingleton(){}

}

The advantage the above code will provide is, synchronized block will not be executed once value is assigned to singleton ref. This strategy is known as double check locking(double check locking doesn't work pre 1.5 JDK).