Design Patterns - Singleton inJava with example

This post is about Singleton Design pattern in java. All of us may know, there are different way to create singleton instance of class. I am going to write one of them. How we can make singleton object. But before going further, we will first learn what singleton is?

What is Singleton?

Singleton is design pattern which comes under creational pattern. Sometimes, it is important to have one instance of class or we can say, it provide single global entry point to the object.

How we can create Singleton?

There are many ways to create Singleton. Each one of them have their pros and cons. Today, we will discuss how to create Singleton with lazy Initialization with SingletonInstanceHolder class.

package singleton;

public class Singleton {
 
 private static class SingletonInstanceHolder {
  private static int MODCOUNT = 0;
  private static Singleton INSTANCE = null;
  
  private static final Object MUTEX = new Object();
  static
  {
   if (INSTANCE == null)
   { 
    synchronized (MUTEX) {
     if (INSTANCE == null)
      try {
       INSTANCE = new Singleton();
      } catch (IllegalAccessException e) {
       // TODO Auto-generated catch block
       e.printStackTrace();
      }
    }
   }
  }
 }
 
 private Singleton() throws IllegalAccessException {
  if(SingletonInstanceHolder.MODCOUNT > 0)
   throw new IllegalAccessException("Multiple instance"); 

  SingletonInstanceHolder.MODCOUNT++;
 }
 
 public static final Singleton getInstance() {
  return SingletonInstanceHolder.INSTANCE;
 }
 
 // Avoiding duplicate objects with serialization
 public Object readResolve() {
  return getInstance();
 }
}

The above mentioned class Singleton. This class can't have multiple objects even using reflection api because our code will throw exception if more than one instance is created with reflection.

package singleton;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class SingletonTest {
  public static void main(String[] args) throws ClassNotFoundException, SecurityException, NoSuchMethodException, InstantiationException,
     IllegalAccessException, IllegalArgumentException,InvocationTargetException {
 
  Class demo = Class.forName("singleton.Singleton");
  Constructor con = demo.getDeclaredConstructor();
  con.setAccessible(true);
  
  for(int i=0; i<10; i++) {
   Singleton s1 = (Singleton) con.newInstance();
   System.out.println(s1.toString());
  }
 }
}

The above code when run will throw following exception. It shows that the Singleton class's object will be created only once and then it will throw exception if tried to called constructor multiple times even with reflection.

Exception in thread "main" java.lang.reflect.InvocationTargetException
 at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
 at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
 at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
 at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
 at singleton.SingletonTest.main(SingletonTest.java:15)
Caused by: java.lang.IllegalAccessException: Multiple instance
 at singleton.Singleton.<init>(Singleton.java:29)
 ... 5 more

2 comments :

  1. Hi Dude,


    As i am seeing that you are using double lock while creating the newInstance,

    have you taken care of cache coherence ? Else you will see your application crashing.. Here is link that might help you :

    http://en.wikipedia.org/wiki/Double-checked_locking

    ReplyDelete
    Replies
    1. Thanks for the link and comment.

      I would like to explain here that the cache coherence problem will not occur here, I suppose.
      The reason is first of all I am using InstanceHolder initialization class to hold the instance. Other thing is object reference for Singleton is static and double lock checking is also done in static block. Static are loaded only once when the class is loaded in the memory and will never run whether the multiple threads uses or calls the method.

      Delete