Singleton Pattern- Java Design Pattern #2

Reading Time: 3 minutes

In my last blog, we looked into the basics of Design patterns, their importance, and their advantages. So, today we will discuss one of the simplest design patterns that is a singleton and its implementation.

What is Singleton?

So, basically, there are various objects that we only need one of – connection or thread pool, the object used for logging, the object that act like a device driver, etc. And creating more than one object for all the scenarios can create various problems like inappropriate program behavior and result and overuse of resources. So, the Singleton pattern comes into a picture and ensures that only one instance is created. And the object is always instantiated in a lazy manner which is beneficial for the resource-intensive scenario.

 Implementation

So, what we need for the implementation?

  1. A private Constructor
  2. A static factory method
  3. A static field that consists of its only instance

Let’s dive into the implementation.

class Singleton {

//static field
private static Singleton object;

//private Construtor
private Singleton() {}

//static method
public static Singleton getInstance()
{
if (object == null)
object = new Singleton();
return object;
}
}

So, whenever the getInstance() is called for the first time,  a new object is created and after that, it returns the same instance. Looks perfect. Isn’t it?

But suppose you have two threads and each one is executing the above code, so, how many instances is created? Single?

So the answer is NO! the above implementation is not thread-safe. 🙁

So, let’s look into the different approaches to make the above implementation thread-safe.
1) Approach 1:  Make getInstance() a synchronised method.

class Singleton {

//static field
private static Singleton object;

//private Construtor
private Singleton() {}

//static method
public static synchronized Singleton getInstance()
{
if (object == null)
object = new Singleton();
return object;
}

Here, in the above code, the synchronized keyword makes sure that no two threads may enter the method at the same time. So, WOW its a thread-safe! But the problem is that synchronization is expensive. It simply decreases the performance. And moreover, the synchronization is unnecessary once the instance is created.

2) Approach 2: Creating Instance eagerly rather than lazily.

class Singleton {

// Creating an Instance
private static Singleton object = new Singleton();

private Singleton() {}

public static Singleton getInstance() {
return object;
}
}

Again this approach is easy to implement and guarantees thread safety, but actually, now we are creating the instance when class is loaded. So, let’s dive into the last and best approach.

Approach 3: Double-checked locking

In this approach, we only synchronize the very first time when the instance is created, otherwise not.

class Singleton {
private volatile static Singleton object;private Singleton() {}public static Singleton getInstance() {
if (object == null) {
synchronized (Singleton.class) {
if (object == null)
object = new Singleton();
}
}
return object;
}
}

We have added a volatile keyword with the static field and synchronization block. So, now we don’t have an overhead of calling synchronized methods every time. We basically synchronized for the very first time. It not only guarantees thread safety but also better performance.

Conclusion

So, we have learned about the Singleton design pattern, its classic implementation, and the different way of implementing Singleton design patterns for a multithreaded environment. And comes up with the conclusion that double-checked locking is the best approach.

Please feel free to provide your suggestions. 🙂 Please comment if you have some queries and want to add some points.

References:
A book: Head First Design Patterns

blog-footer