Singleton Design Pattern with Java

Mustafa Furkan AYAZ
5 min readSep 21, 2022

Singleton design pattern is considered in the category of creational design patterns. In the Singleton design pattern, only one object of a class must be created and this instance can be accessed globally. Thus, when an object belonging to a class is needed, it will be possible to use the same instance instead of creating a new instance each time. In order to achieve this situation we mentioned, we will first need to change the constructor structure that we are used to. Because by using the new keyword, re-creation operations can be done through the same class. That’s why we’re going to make changes in the constructor to limit the use of newkeyword.

Solution

1- First, we need to use a constructor that is defined as private. Thus, within other classes, a new object cannot be created with the new keyword from the class designed as a singleton.

2- Also, we need to set up an instance defined as static in the class and a method structure that will create a new object by accessing this instance. This static method will work like a constructor when viewed from the outside and will use the private constructor in its inner world.

In this section, we will examine the part that I tried to explain verbally in detail, through the code, in the continuation of the article.

If we want to associate the singleton design with the real world, we can liken it to the government that countries have. In this case, a country must have a government. Regardless of the characteristics of the people living in the country, people living in this country will be classified as “citizens of government X”.

Java Code Structure

Eager Initialization

We can apply what we have mentioned so far to the code as follows.

First of all, we will examine the structure prepared with Eager Initialization in this example. In this example, even if the getInstance() method is not called, the instance will be created during class loading.

public class Singleton {

private static Singleton instance = new Singleton();
private static int count;
private Singleton(){
count++;
System.out.println("Constructor is invoked and counter is : " + count);
}

public static Singleton getInstance(){
return Singleton.instance;
}
}

Then, let’s try to create objects from the Singleton class with the getInstance() method from another method.

public class Main {

public static void main(String[] args) {

Singleton singleton = Singleton.getInstance();
Singleton singleton2 = Singleton.getInstance();
Singleton singleton3 = Singleton.getInstance();
Singleton singleton4 = Singleton.getInstance();

}
}

As for the structure we have designed, when the above piece of code runs, we will see the following result in the IDE console.

Constructor is invoked and counter is : 1

In this example, while the Singleton class is loaded, the object creation process for the instance is completed as Eager. Then, the instance return, which is defined as static inside the class, is provided for singleton, singleton2, singleton3 and singleton4. Thus, we can perform operations on the same object without creating a new object each time.

Static Block Initialization

As an alternative to the previous section, we can define the creation step of the instance in a static block.

public class Singleton {

private static Singleton instance;
private static int count;

static {
try {
instance = new Singleton();
} catch (Exception e) {
throw new RuntimeException("Exception occured");
}
}

private Singleton() {
count++;
System.out.println("Constructor is invoked and counter is : " + count);
}

public static Singleton getInstance() {
return Singleton.instance;
}
}

Lazy Initialization

We can use the following code structure to create the object to be created when the getInstance() method is called, not during class loading.

public class Singleton {

private static Singleton instance;

private Singleton(){
System.out.println("Constructor is invoked");
}

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

return Singleton.instance;
}
}

However, it is necessary to take into account a situation that may arise later during this process. If we have a single-threaded application, there will be no problem in using this code structure. However, when a multi-thread structure is in action, more than one thread may try to access the getInstance() method that we have defined. In this case, more than one instance may be created when the code structure that we expect to create a single object is triggered by two threads at the same time. In this case, the Singleton structure will be broken. Therefore, thread-safe singleton structures should be considered.

Thread Safe Singleton

In an application running multiple threads, we can use the synchronized keyword in java so that the globally accessed getInstance() the method can be accessed by only one thread at a time. In this case, the code structure will be as follows. Thus, a second thread that wants to access the method at the same time will wait for the first thread to finish its job first. Thus, the singleton structure will be preserved.

public class ThreadSafeSingleton {

private static ThreadSafeSingleton instance;

private ThreadSafeSingleton(){
System.out.println("Constructor is invoked");
}

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

return instance;
}
}

But in this usage, we are faced with another performance problem. In fact, the problem that may arise with multi-thread is a process that continues only until the first instance is created. But in this case, the threads have to wait for each other even for the 5th and 6th calls on the method. This situation causes losses in terms of performance.

To avoid this situation, the double checked locking principle can be used. With this approach, this situation can be prevented by additionally checking before reaching the synchronized block with an extra if logic.

public class ThreadSafeSingleton {
private static ThreadSafeSingleton instance;

private ThreadSafeSingleton() {
System.out.println("Constructor is invoked");
}

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

return instance;
}
}

Bill Pugh Singleton

Especially before Java 5, due to the memory model problems in Java, the above applications could cause problems if too many threads tried to get singleton objects. Due to this situation, an alternative that does not require the synchronization state was created with the help of a static inner class. As can be seen in the example below, the SingletonHelper class defined as the inner class will not be created in memory while the BillPughSingleton class is being created. However, when the getInstance() method is called, the SingletonHelper class will be loaded and the singleton instance structure we need will be obtained.

public class BillPughSingleton {
private BillPughSingleton() {
System.out.println("Constructor is invoked");
}
private static class SingletonHelper {
private static final BillPughSingleton instance =
new BillPughSingleton();
}

public static BillPughSingleton getInstance() {
return SingletonHelper.instance;
}
}

Pros

Thanks to the singleton structure, it is guaranteed that only one instance of each class will be created. At the same time, this instance can be accessed globally.

Cons

Considering multi-thread, extra effort is required to implement the singleton pattern. Also, since we have created a private constructor in terms of structure, it may be necessary to operate through the public constructor in various test frameworks. In this case, we may run into problems.

Summary

In this article, I tried to mention what Singleton Design Pattern is and how to implement it in java. Thanks to this structure we have used, we have seen that only one object of each class will be created and it is possible to use this instance in case of need without the need to produce a new one.

--

--

Mustafa Furkan AYAZ

I graduated from Bilkent University, Department of Electrical and Electronics Engineering in 2021. I started my career in the software development industry.