Singleton pattern in java

Singleton design pattern allow creation of only single instance of class. It is one of the creational design pattern, mentioned in Design Patterns book. What we know at this point, first that this pattern related to creation of object, second only a single object of a class can be created.

Why we require this in first place. Imagine you are working on application that talks to the database. So, you require some kind of connection instance to talk to database. And there is a limit on how many connections you can create. Let us assume only one connection is allowed by database administrators for our application. But this connection instance is used by different places in our application.

With this requirement in mind, We know that usual way to get the instance of a class is using new keyword (like new MyConnectionClass). But if we write that in our application, it will create n objects where n is number of times the constructor is called using new.

So, what is the solution of this problem, one straight forward way is to first stop the calling of new constructor from outside of the class. That can be done by making the constructor private.

class MyConnectionClass {
  private MyConnectionClass() {}
}

Now, we need some kind of method that returns the same instance every time it is called. So, how can we ensure that it returns the same instance. We can do it by making a private static final field in a class and returning it from our public method. Look at the below code, to see what i am talking about.

class MyConnectionClass {
  private static final MyConnectionClass instance = new MyConnectionClass();

  private MyConnectionClass() {}

  public getInstance() {
    returns instance;
  }
}

Above code example is the most basic example of singleton pattern but there are many variations of this pattern. I will discuss them here. But First look at the line in above code that is private static final MyConnectionClass instance = new MyConnectionClass(); Here as you can see, object of the class are created when this class are loaded by JVM. So, we can say that object are eager initialized. But if you want to initialize instance lazily, for example - to create object when the method is first called, we write code that looks something like below code.

class MyConnectionClass {
  private static MyConnectionClass instance;

  private MyConnectionClass() {}

  public getInstance() {
    if (instance == null) {
      instance = new MyConnectionClass();
    }
    returns instance;
  }
}

Comparing this code with the above code, see we are no longer defining an instance as final, and inside the getInstance method we are first comparing instance reference with null. If it is null we are calling the constructor, otherwise returning instance as it is. If you are using this pattern in single threaded environment, it is fine. But in multithreaded environment, this pattern can lead to race condition resulting in more than one instance to be created.

At this point, I have given two examples, first eager loaded and second lazy loaded. But second one is not thread safe. Let's view the classification diagram.

Even though, i have given the example of Basic Singleton and Lazy Singleton. In following sections, i will be giving the examples of all the patterns as given in classification diagram.

In this section

  1. Basic singleton
  2. Static block singleton
  3. Lazy singleton
  4. Synchronized method singleton
  5. Double locking synchronized singleton
  6. Inner static singleton
  7. Enum based singleton

Basic Singleton

It is the simplest singleton pattern with eager loading of instance.

public class BasicSingleton {

    int value = 0;
    private static final BasicSingleton INSTANCE = new BasicSingleton();
    private BasicSingleton(){}

    public static BasicSingleton getInstance() {
        return INSTANCE;
    }

    public int getValue() {
        return value;
    }

    public void setValue(int value) {
        this.value = value;
    }
}

In above code example, I have taken a field value. You can test the singleton of the class by first creating an instance and setting some value to this field value, say 5. Now, create another instance (by calling getInstance() method) of the class. Now if you get the value of field value, you will notice that its value is 5 that we have set earlier. Or you can even print the hashcode of both the instances and compare them.

Static Block Singleton

Static block singleton is another way we can eager initialize instance. One benefit of using this pattern is that, if the creation of instance is complex or it can throw exception then using this pattern we can handle the exception in the static block itself. Look at the following code, and see our constructor is throwing the exception.

import java.io.File;
import java.io.IOException;

public class StaticBlockSingleton {
    int value = 0;
    private static StaticBlockSingleton instance = null;

    static {
        try {
            instance = new StaticBlockSingleton();
        } catch (IllegalArgumentException | IOException e) {
            System.out.println("Failed to initialize singleton ");
        }
    }

    private StaticBlockSingleton()
        throws IllegalArgumentException, IOException {
        System.out.println("Initializing singleton");
        File.createTempFile(".", ".");
    }

    public static StaticBlockSingleton getInstance() {
        return instance;
    }

    public int getValue() {
        return value;
    }

    public void setValue(int value) {
        this.value = value;
    }
}

Lazy Singleton

As the name suggest, it is lazy way to initialize the instance but the major drawback of this pattern is that it is not thread safe.

public class LazySingleton {

    int value = 0;
    private static LazySingleton instance;
    private LazySingleton() {}

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

    public int getValue() {
        return value;
    }

    public void setValue(int value) {
        this.value = value;
    }
}

Synchronized method singleton

It is improvement over lazy singleton example. It is done by making the getInstance synchronized. This approach will make our singleton class thread safe but writing synchronized in front of method name is not a good approach as it will lock the object/class.

In our case, we are writing synchronized in front of static method. So, the thread calling our method acquire the lock at class level which block any other thread from accessing other synchronized static method while one thread is inside our synchronized static method.

Here is the example of this approach, in later section I will discuss the other approaches of synchronization.

public class SynchronizedMethodSingleton {

    int value = 0;
    private static SynchronizedMethodSingleton instance;
    private SynchronizedMethodSingleton() {}

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

    public int getValue() {
        return value;
    }

    public void setValue(int value) {
        this.value = value;
    }
}

Double locking synchronized singleton

This approach is an improvement over Synchronized method singleton. Here we are only synchronising the critical section of getInstance method and which is if (instance == null). Let me give the example without double locking.

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

This code uses the synchronized block but still it is not performant because every time getInstance method is called, the synchronized block is executed irrespective of instance is null or not. So now, I will present you the example to Double locking synchronized singleton.

public class DoubleLockingSingleton {

    int value = 0;
    private static volatile DoubleLockingSingleton instance;
    private DoubleLockingSingleton() {}

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

    public int getValue() {
        return value;
    }

    public void setValue(int value) {
        this.value = value;
    }
}

Using double locking we ensure that synchronized block is executed only if the instance is null and not other times. There is one other point I want you to consider which is volatile declaration of instance. It is important to make the field volatile as helps in visibility.

To understand, let's imagine we declared the instance field without volatile. So, without it, jvm can rearrange instructions. Look at this line instance = new DoubleLockingSingleton();. Without volatile it is possible that instance variable is marked as not null but the constructor DoubleLockingSingleton is still executing (left hand side executed before right hand side). At this moment instance does not point to fully constructed instance and when another thread access it. Our application might crash. It is also important to note that this approach with volatile only works with java 4 and above.

Inner static singleton

This approach uses static inner class and its is both lazy loaded and thread safe. Also code is pretty simple. Let's look at the example.

public class InnerStaticSingleton {

    private InnerStaticSingleton(){}

    private static class Impl {
        private static final InnerStaticSingleton instance =
            new InnerStaticSingleton();
    }

    public InnerStaticSingleton getInstance() {
        return Impl.instance;
    }
}

Enum based singleton

We can also use enum to create singleton as only finite amount of instances can be created with enum. With the patterns defined in above cases the singleton can be broken by reflection or serialization. But enum based singleton is protected by these issues (there is a caveat with serialization of enum, as fields are not serialized in enum).

public enum EnumBasedSingleton {
    INSTANCE;
    private int value;

    EnumBasedSingleton() {
        value = 10;
    }

    public int getValue() {
        return value;
    }

    public void setValue(int value) {
        this.value = value;
    }
}

We also have to consider that enum cannot be inherited. So, if we want to do inheritance we cannot use this pattern.

Summary

In this article, I have shown the patterns of creating singleton, such that only one instance of the class is created. I have classified these patterns on the basis of eager/lazy loaded and thread safety.

If you liked this article, consider following me on X where I will be announcing for new posts.