Thursday 20 October 2011

Singleton not behaving as a singleton


What is Singleton Design Pattern:

Singleton is the simplest creational design pattern and is widely used by program designer. So, I thought of sharing my understanding on singleton DP as my first post.

A singleton is a class that can be instantiated only one time in a JVM per class loader. Repeated calls always return the same instance. Ensures that a class has only one instance, and provide a global point of access.

The UML diagram of Singleton Class is surprisingly simple because Singleton consists of a simple class that holds a reference to a single instance of itself



The purpose of Singleton design pattern is to control the object creation process and limiting it to one instance. But as a design engineer, we need to make it flexible enough such that it can easily extendible to “doubleton” or any N-ton class.

Well, a singleton can be created, but it can't be instantiated by developers - meaning that the singleton class itself takes the control of creating object. The restriction on the singleton is that there can be only one instance of a singleton created by the Java Virtual Machine (JVM) - by prevent direct instantiation we can ensure that developers don't create a second copy.

As a starting point, we can define a class as –

public class MySingleton {
            public static MySingleton mMySingletonObj = new MySingleton();
}

Now, the question is, is it a Singleton? Apart from design limitation, this class is having many other drawbacks.

Let’s try with a main class

public class mainC {

            public static void main(String[] args) {   
                        MySingleton objOne = new MySingleton();                     
                        MySingleton objTwo = new MySingleton();
            }
}

Oops, we got multiple objects. How to prevent it? Well, provide a default constructor and mark it private

public class MySingleton {
            public static MySingleton mySingletonObj = new MySingleton();
            private MySingleton() {}
}

Now, try to compile the previous main class (mainC.java). So, to some extent, it is a singleton. But, extend it and perform some crazy experiment, this class will lose its property. Think over it !!!

Now, let’s try out another way to define a Singleton

public class MySingleTon { 
    // flag to check the instance
    private static MySingleTon _myInst= null;
    private MySingleTon() {
    }
    public static MySingleTon getInstance() {
            if (_myInst== null) {
                        _myInst = new MySingleTon();
            }
            return _myInst;
    }
}

So far so good. We prevent direct instantiation (private constructor) and provide a way to get the reference to an instance of the singleton object. We are intelligent enough and that is why we made getInstance a static member and store the instance in a private member.

When first called, the getInstance() method creates a singleton instance, assigns it to a member variable, and returns the singleton. Subsequent calls will return the same singleton. The design is flexible enough to add new functionality to the singleton object by adding new methods. But, still we are not constructing THE perfect singleton class. Think from multithreaded environment prospective. Is it thread safe? Oops!!!

Well, we can protect out getInstance() method from threat of Thread Synchronization problem by using synchronized  keyword.

public static synchronized MySingleTon getInstance() {
            if (_myInst== null) {
                         _myInst = new MySingleTon();
            }
            return _myInst;
 }

Happy??? But being a good java designer you should not. Assume that our getInstance()method is not as simple as mentioned above and it is having other stuff also (I am also assuming).  So, we can do something else. It is always good idea to block the race condition code rather than blocking the entire method. So let’s block the sensitive info

public static MySingleTon getInstance() {
            if (_myInst== null) {
                        synchronized (MySingleTon.class) {
                                    if (_myInst== null) {
                                                _myInst = new MySingleTon();
                                    }
                                    }
            }
            return _myInst;
}

We moved the synchronization to the block level rather than the method level.

Advantage: Fine Gain Control, if multiple threads are entering the code, we are making sure that the waiting time is minimal for all the threads, as we have synchronized only the code which really requires synchronization. It is resolved using “Double Type Checking”.

For the very first time this problem may arise. Let say Thread1 has executed “if (_myInst== null)” statement, and swapped out (may be CPU time slice), another thread say Thread2 got the chance to run and it executed the same statement “if (_myInst== null)” and acquired the lock on “MySingleTon.class”, and now Thread2 is running and will create the new Singleton() class , now when Thread1 wakes up it will also acquire the lock on “Singleton.class” and will   create one more instance of the Singleton class, which is what we don’t want.

Are we finished?? Sorry we are still not done. If you serialize your class and deserialize it twice, there will be multiple instances of Singleton class. Where there's a will, there's a way – we can use readResolve() method, in order to return the Singleton object read, it will make sure only one instance is returned back.

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

Do you think we are done? Not yet.

public class CloneMainClass {
            public static void main(String[] args) {
                        // Get a singleton
                          MySingleTon mySingObj = MySingleTon.getInstance();                           
                          MySingleTon mySingCloneObj = (MySingleTon) mySingObj.clone();
            }
}

This is correct. So, we are virtually getting two Singleton Objects. To make out class a perfect singleton, we have to add clone() method and simply through CloneNotSupportedException exception.

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

Still there are few ways using which you can make multiple instances of this Singleton implementation - Multiple Singletons Simultaneously Loaded by Different Class Loaders. To avoid this we have to make sure that that Singleton object is loaded by only one class loader peeking through code.

To summarize it, let us find out the merits and demerits of singleton design pattern




Merits
Self Control: Singleton prevents other objects from instantiating their own copies of the Singleton object, ensuring that all objects access the single instance.
Flexibility: Because the class controls the instantiation process, the class has the flexibility to change the instantiation process.

Demerits

Overhead: There is some overhead involved in checking whether an instance of the class already exists every time an object requests a reference
Object lifetime: Though, as a java programmer we don’t have to think much on cleaning the object, other programmer needs to find out a way to clean up the singleton object

So, I am singing off now. Please share you thought with us.