Single object for Singleton pattern


I have explained the basics of singleton pattern here https://vtkrishn.wordpress.com/2010/03/26/singleton-pattern-revisited/

The design goes like this

1) private constructor
2) static method to return the single objects

In this post I am going to explain some additional restrictions on this pattern

1) Lazy initialization with double lock mechanism

2) Early initialization

3) Serialization

4) ClassLoaders

5) Restrict Cloning

Lazy instantiation using double locking mechanism

The standard implementation shown in the code above is a thread safe implementation, but it’s not the best thread-safe implementation because synchronization is very expensive when we are talking about the performance. We can see that the synchronized method getInstance does not need to be checked for synchronization after the object is initialized. If we see that the singleton object is already created we just have to return it without using any synchronized block. This optimization consist in checking in an un-synchronized block if the object is null and if not to check again and create it in an synchronized block. This is called double locking mechanism.

In this case case the singleton instance is created when the getInstance() method is called for the first time. This is called lazy instantiation and it ensures that the singleton instance is created only when it is needed.

//Lazy instantiation using double locking mechanism.
class Singleton
{
 private static Singleton m_instance;

 private Singleton()
 {
 System.out.println("Singleton(): Initializing Instance");
 }

 public static Singleton getInstance()
 {
 if (m_instance == null)
 {
 synchronized(Singleton.class)
 {
 if (m_instance == null)
 {
 System.out.println("getInstance(): First time getInstance was invoked!");
 m_instance = new Singleton();
 }
 }
 }

 return m_instance;
 }

 public void doSomething()
 {
 System.out.println("doSomething(): Singleton does something!");
 }
}

Early instantiation using implementation with static field

In the following implementattion the singleton object is instantiated when the class is loaded and not when it is first used, due to the fact that the m_instance member is declared static. This is why in this implementation we don’t need to syncronize any portion of the code. The class is loaded once this guarantee the unicity of the object

//Early instantiation using implementation with static field.
class Singleton
{
 private static Singleton m_instance = new Singleton();

 private Singleton()
 {
 System.out.println("Singleton(): Initializing Instance");
 }

 public static Singleton getInstance()
 {
 return m_instance;
 }

 public void doSomething()
 {
 System.out.println("doSomething(): Singleton does something!");
 }
}

Serialization

If the Singleton class implements the java.io.Serializable interface, when a singleton is serialized and then deserialized more than once, there will be multiple instances of Singleton created. In order to avoid this the readResolve method should be implemented. See Serializable () and readResolve Method () in javadocs.

 public class Singleton implements Serializable {
 ...

 // This method is called immediately after an object of this class is deserialized.
 // This method returns the singleton instance.
 protected Object readResolve() {
 return getInstance();
 }
 }

ClassLoaders

If you have multiple classloaders(possibilities in case of servlet container) then the patterns will allow for multiple instances to be created which is not expected
To overcome this you have to have the custom implementation like

private static Class getClass(String classname)
 throws ClassNotFoundException {
 ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
 if(classLoader == null)
 classLoader = Singleton.class.getClassLoader();
 return (classLoader.loadClass(classname));
 }
}

Restrict Cloning

You can overcome cloning of the singleton object by explicitly throwing cloneNotSupportedException

public Object clone() throws CloneNotSupportedException {
 throw new CloneNotSupportedException();
 }

If we try to access the above singleton object using reflection then you will get

Exception in thread "Main Thread" java.lang.IllegalAccessException: Class com.example.thread.Main can not access a member of class com.simple.NormalClass with modifiers "private"
 at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:65)
 at java.lang.Class.newInstance0(Class.java:349)
 at java.lang.Class.newInstance(Class.java:308)
 at com.example.thread.Main.main(Main.java:10)

if you are using java 1.5 and above you can use enum type which takes care of all the above


public enum Singleton{
INSTANCE;

public static void print(){
System.out.println("hi");
}

public class Main{

public static void main(String[] args) {
Singleton.INSTANCE.print();
}
}
}

9 thoughts on “Single object for Singleton pattern

  1. Pingback: Breaking singleton pattern « They point the finger at me.. again!

  2. Pingback: Tweets that mention Single object for Singleton pattern « They point the finger at me.. again! -- Topsy.com

  3. Florimon van Putte

    The ‘double locking idiom’ is indeed considered broken. The recommended approach now is something like:

    public class Singleton {

    public Singleton() {
    System.out.println(“Singleton constructed”);
    }

    public static Singleton getInstance() {
    return LazyLoader.singleton;
    }

    public static void main(String… args) {
    System.out.println(“In main, going to get instance”);
    getInstance();
    System.out.println(“In main, got instance”);
    }

    private static class LazyLoader {
    private static Singleton singleton = new Singleton();
    }
    }

    Reply
  4. Ramon Ramos

    The new recommended approach is to use an enum for the implementation as stated by Joshua Bloch in “effective java”.

    Reply
  5. Pingback: Cheatsheet: 2011 02.23 ~ 02.28 - gOODiDEA.NET

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s