Monday, October 11, 2010

LazyHolder Pattern

Design Pattern

A pattern describes a proven solution to a recurring design problem, placing particular emphasis on the context and forces surrounding the problem, and the consequences and impact of the solution. Find more details about design patterns in http://java.sun.com/blueprints/corej2eepatterns/Patterns/index.html

Singleton Pattern

This pattern helps to create only one instance of a class in a ClassLoader. This is achieved by holding the created object in class level variable.

Eagerly Initialization:

Following are the points needs to be done

  • All constructor method has to be decalared with private access specifier
  • A variable has to be declared to hold the object with private access specifier and static and finalaccess modifier and singleton object created and assigned here itself
  • A method has to be created with public access specifier and static access modifier
SingleTonEarlyInitialization.java

public class SingleTonEarlyInitialization {
private static final SingleTonEarlyInitialization sObj = new SingleTonEarlyInitialization();

private SingleTonEarlyInitialization() {}

public static SingleTonEarlyInitialization getInstance() {
return sObj;
}
}

Lazy Initialization:

Following are the points needs to be done

  • All constructor method has to be decalared with private access specifier
  • A variable has to be declared to hold the object with private access specifier and static access modifier
  • A method has to be created with public access specifier and static access modifier and object will be created and returned from here.
SingleTonLazyInitialization.java

public class SingleTonLazyInitialization {
private static SingleTonLazyInitialization sObj = null;

private SingleTonLazyInitialization() {
}

public static SingleTonLazyInitialization getInstance() {
if(null == sObj)
sObj = new SingleTonLazyInitialization();
return sObj;
}
}

Thread Safe

In multi-threaded environment, Lazy Initialization based singleton is not threadsafe. Hence, getInstance() method has to be enforced with class level monitoring to achieve threadsafe.

Option 1 - Make getInstance() as Synchronized method
public static synchronized SingleTonLazyInitialization getInstance() {  
  if(null == sObj)
  sObj = new SingleTonLazyInitialization();  
  return sObj;
 }
Option 2 - Introduce Synchronized block on the class
public static SingleTonLazyInitialization getInstance() {
  synchronized(SingleTonLazyInitialization.class)
  {
  if(null == sObj)   
  sObj = new SingleTonLazyInitialization();
  }  
  return sObj;
 }
Option 3 - Introduce Synchronized block on the dummy Object
private static final Object lockObj=new Object();
 public static SingleTonLazyInitialization getInstance() {  
  synchronized(lockObj)
  {
  if(null == sObj)   
  sObj = new SingleTonLazyInitialization();
  }  
  return sObj;
 }
Performance Bottleneck

Introducing the synchronized block/method performs slightly slower than the normal and causes performance bottleneck. In the object instantiation time, we need to make sure that not more than one object get instantiated. Afterwards, any number of threads can possibly access with zero delay. While introducing the synchronized block/method, some delay may occur.

To overcome this delay, we may need to introduce the null-if check before obtaining the monitoring-lock.

private static final Object lockObj=new Object();
 public static SingleTonLazyInitialization getInstance() {
  if(null != sObj)
   return sObj;  
  synchronized(lockObj)
  {
  if(null == sObj)   
  sObj = new SingleTonLazyInitialization();
  }  
  return sObj;
 }

LazyHolder Pattern

Before object initialization itself, we get more than 100 threads span and waits to obtain the lock on synchronized block, then the above sample also will not perform good.

As per Java Language Specification, in JVM, class load and initialization phase is serial. Utilizing this as an advantage, we can initialize the singleton object through some other class initialization phase. This approach works as on-demand(lazy loading) initialization object.

public class SingletonLazyHolder { 
 private SingletonLazyHolder() {
 }
 
 private static class LazyHolder {
  private static final SingletonLazyHolder sObj = new SingletonLazyHolder();
 }
 
 public static SingletonLazyHolder getInstance() {  
  return LazyHolder.sObj;
 }
}

Multiton Pattern

Multiton pattern alows to have map of named instances as key-value pairs, in which getInstance() method key has to be passed and specific instance get initialized and returned.

MultitonSample.java:
import java.util.HashMap;
import java.util.Map;

public class MultitonSample {
 private static final Map<String,MultitonSample> maps = new HashMap<String,MultitonSample>();

 private MultitonSample() {
 }

 public static MultitonSample getInstance(String key) {
  MultitonSample mObj = null;
  synchronized(maps)
  {
   mObj = maps.get(key);
   if(null == mObj)
   {
    mObj = new MultitonSample();
    maps.put(key, mObj);
   }
  }
  return mObj;
 }
}

No comments:

Post a Comment

Recent Posts

Unix Commands | List all My Posts

Texts

This blog intended to share the knowledge and contribute to JAVA Community such a way that by providing samples and pointing right documents/webpages. We try to give our knowledege level best and no guarantee can be claimed on truth. Copyright and Terms of Policy refer blogspot.com