Monday, April 13, 2009

Using the Singleton Design Pattern in a multithreaded environment

Let's take a look first at the definition of the Singleton Pattern.

The Singleton Pattern ensures a class has only one instance, and provides a global point of access to it.

Here the implementation of this definition :

public class Singleton {

/** The unique instance **/
private static Singleton instance;

/** The private constructor **/
private Singleton() {}

public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}

There is a problem with the code above in a multithreaded environment. Two threads might get ahold of two different instances if they enter at same time in the getInstance method.

So how to deal with multithreading ?

This problem can be fixed using the synchronized keyword.

public class Singleton {

/** The unique instance **/
private static Singleton instance;

/** The private constructor **/
private Singleton() {}

public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}

The getInstance method is now synchronized so we force every threads to wait its turn before it can enter the method. This solution fixes our problem but it is very expensive. Indeed we only need synchronization for the first call. After that synchronization is totally unneeded. Remember that synchronization decreases performance by a factor of 100.

A solution consists of relying on the JVM to create our instance when the class is loaded. You can use this solution if the overhead of the creation and runtime aspects of the singleton are not onerous.

public class Singleton {

/** The unique instance **/
private static Singleton instance = new Singleton();

/** The private constructor **/
private Singleton() {}

public static Singleton getInstance() {
return instance;
}
}
Since Java 1.5, there is a new approach to implement Singletons. Simply make it an enum type :

public enum Singleton {

INSTANCE;

//Singleton method
public void someMethod( ) {...}
}
Accessing the enum singleton :
Singleton.INSTANCE.someMethod( );

If you don't want to automatically create an instance of your singleton when the JVM start, there is another solution called "double-checked locking". With this solution, we first check to see if an instance is created and only then we synchronize. This way we only synchronize the first call and there's no performance issue anymore. Another requirement is to use the volatile keyword for the Singleton instance.

public class Singleton {

/** The unique instance **/
private volatile static Singleton instance;

/** The private constructor **/
private Singleton() {}

public static Singleton getInstance() {
if (instance == null) {
synchronized(Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}

return instance;
}
}

!!! This solution will not work in Java 1.4 or earlier. Many JVMs in Java version 1.4 and earlier contains implementation of the volatile keyword that allow improper synchronization fo double checed locking.

Here's an interresting article on the double-checked locking pattern and the use of the volatile keyword.

Another article in french.

10 comments:

  1. Still you won't have a full-proof singleton which can work on mulitthreaded enviornment and every OS.
    Its really so tough to have full-proof Singleton.
    Easy wasy would be to make your Singleton as Enum type .

    ReplyDelete
    Replies
    1. I agree Enum is best way to implement Singleton pattern in Java 5 world. It automatically handles Serializable Singleton and thread-safe creation.

      Delete
  2. Thanks for the comment. Indeed since Java 1.5 we can now declare a singleton as an Enum type. I'll make an update to illustrate this.

    ReplyDelete
  3. The best way to achieve this goal(singleton dp) is to implement Singleton as Enum cause when Singleton should be serializable, it's very easy to forget to implement readResolve() method...

    ReplyDelete
  4. Enums are not the solutions if you need to implement interfaces or extend other classes. Then you'd need to stick to the last solution mentioned

    ReplyDelete
  5. Hi
    Use of volatile is not neccessary if the variable is static. It is only required if the variable is non static.

    Thanks
    Ram

    ReplyDelete
  6. why we declare static in "private volatile static Singleton instance;"?

    ReplyDelete
  7. I have one doubt regarding this, first time it creates one singleton object its fine. but 2nd time 100 request came at a time. all checks the object is null or not. It was not null, then all shares the same object.

    Here my question is if all threads shares the same object.
    case 1) If one thread update the state of the singleton object, it will impact on second thread, 3rd thread.... because they also using same object.

    case 2) if we are synchronise that object only one thread can access at a time. but it is not good at banking applications. because N number of users are doing transactions at time. In this situation how singleton handle ?

    ReplyDelete
  8. I have one doubt regarding this, first time it creates one singleton object its fine. but 2nd time 100 request came at a time. all checks the object is null or not. It was not null, then all shares the same object.

    Here my question is if all threads shares the same object.
    case 1) If one thread update the state of the singleton object, it will impact on second thread, 3rd thread.... because they also using same object.

    case 2) if we are synchronise that object only one thread can access at a time. but it is not good at banking applications. because N number of users are doing transactions at time. In this situation how singleton handle ?

    --- Ravi Kumar Badavatu

    ReplyDelete