Monday, August 20, 2012

Singleton Class in Java

It was my first interview when I got this question, Can you design a class for which you can create only one object?? At that time it went above my head and then i searched what is this all about and got to know about singleton pattern. In one of my latest interview once again this question was asked but this time it was something like this "Can you design a singleton class??How will you test it??What if I serialize and then deserialize the object, won't it create two different objects??What if we have multiple classloaders?? Lets see.

My first Singleton Class


class Singleton {
   
    private static Singleton sg=null;
    private Singleton(){
     
    }
    public static Singleton getInstance() throws Exception{
        if ( sg == null){
            sg = new Singleton();
        }  
        return sg;
    }
}

So far so good!! This example works fine in single threaded programs. Lets take the case of multi threaded programs, I have two threads t1 and t2 who called getInstance() method, t1 came in checked that sg is null by the time it can instantiate, JVM comes in and suspends the thread and starts the t2, t2 comes in checks sg is null creates a new object and returns, JVM brings t1 now since t1 already had checked so it will go for creating the new object and returns it. You are doomed, Your JVM has two instances of a singleton class. So we need synchronization, lets modify our class.


class Singleton {
   
    private static Singleton sg=null;
    private Singleton(){
     
    }
    public static synchronized Singleton getInstance() throws Exception{
        if ( sg == null){
            sg = new Singleton();
        }  
        return sg;
    }



So multiple threads problem solved, but is everything okay with this class?? Isn't it too expensive to synchronize the getInstance method given the fact that you need it only the first time?? Lets see one more conservative way :

class Singleton {
     
      public final static Singleton sg = new Singleton();
      private Singleton(){
   
      }
}

So we have two options either synchronize the getInstance() or use the above implementation. Next on multiple class loaders and serialization in next post.





1 comment: