Monday 11 March 2013

Thread Safety in Java Singleton Classes

Leave a Comment

Singleton is one of the most widely used creational design pattern to restrict the object creation by applications. In real world applications, resources like Database connections or Enterprise Information Systems (EIS) are limited and should be used wisely to avoid any resource crunch. To achieve this, we can implement Singleton design pattern to create a wrapper class around the resource and limit the number of object created at runtime to one.
In general we follow below steps to create a singleton class:
  1. Override the private constructor to avoid any new object creation with new operator.
  2. Declare a private static instance of the same class
  3. Provide a public static method that will return the singleton class instance variable. If the variable is not initialized then initialize it or else simply return the instance variable.
Using above steps I have created a singleton class that looks like below:
package com.harit;
 
public class ASingleton {
 
    private static ASingleton instance = null;
 
    private ASingleton() {
    }
 
    public static ASingleton getInstance() {
        if (instance == null) {
            instance = new ASingleton();
        }
        return instance;
    }
 
}
In the above code, getInstance() method is not thread safe i.e multiple threads can access it at the same time and for the first few threads when the instance variable is not initialized, multiple threads can enters the if loop and create multiple instances and break our singleton implementation.
There are three ways through which we can achieve thread safety.
1. Create the instance variable at the time of class loading: Pros:
  • Thread safety without synchronization
  • Easy to implement
Cons:
  • Early creation of resource that might not be used in the application.
  • The client application can’t pass any argument, so we can’t reuse it. For example, having a generic singleton class for database connection where client application supplies database server properties.
2. Synchronize the getInstance() method: Pros:
  • Thread safety is guaranteed.
  • Client application can pass parameters
  • Lazy initialization achieved
Cons:
  • Slow performance because of locking overhead.
  • Unnecessary synchronization that is not required once the instance variable is initialized.
3. Use synchronized block inside the if loop: Pros:
  • Thread safety is guaranteed
  • Client application can pass arguments
  • Lazy initialization achieved
  • Synchronization overhead is minimal and applicable only for first few threads when the variable is null.
Cons:
  • Extra if condition
Looking at all the three ways to achieve thread safety, I think third one is the best option and in that case the modified class will look like:
package com.harit;
 
public class ASingleton{
 
    private static ASingleton instance= null;
    private static Object mutex= new Object();
    private ASingleton(){
    }
 
    public static ASingleton getInstance(){
        if(instance==null){
            synchronized (mutex){
                if(instance==null) instance= new ASingleton();
            }
        }
        return instance;
    }
 
}

0 comments:

Post a Comment