Reading Time: 6 minutes

Singleton Creational Design Pattern Java Explained [Code Example]

Singleton Creational Design Pattern

Singleton Creational Design Pattern is a part of the classic Gang Of Four Creational Design Patterns. These deal with the creation/instantiation of Java Class objects in the best possible way in specific scenarios.

The basic way of creating an object i.e using the new operator and class constructor sometimes is not enough to deal with modern complexities in the System Design. To tackle such issues, we have below 5 Creational Patterns which could be used in specific scenarios:

  1. Singleton Pattern
  2. Factory Pattern
  3. Abstract Factory Pattern
  4. Builder Pattern
  5. Prototype Pattern

This tutorial is a part of the Creational Design Pattern Series. Take a look at other Creational Design Patterns:

  1. Singleton Creational Design Pattern Java Explained [6 Code Example]
  2. Factory Design Pattern Java Simplified [Simple Real World Example]
  3. Factory Method Design Pattern Java Simple Detailed Examples
  4. Abstract Factory Design Pattern Java Real World Example
  5. Builder Design Pattern Java Real World Example
  6. Prototype Design Pattern Java Real World Example

 

Singleton Creational Design Pattern

Singleton Creational Design Pattern is one of the most basic Gang of Four (GOF) design patterns. As the name suggests, this pattern will ensure that only a single instance of the class is created in the application.

Singleton design is very controversial among developers because of its design implementation concerns. Singleton design pattern is also used in other design patterns like Abstract Factory, Builder, Prototype, Facade, etc.

  • To implement the Singleton pattern, we have different approaches but all of them have the following common concepts.
  • Private constructor to restrict instantiation of the class from other classes. Also to ensure that this class doesn’t have any child classes.
  • The private static variable of the same class that is the only instance of the class.
  • Public static method that returns the instance of the class, this is the global access point for the outer world to get the instance of the singleton class.

 

We have different ways to implement the Singleton Creational Design Pattern :

  1. Eager Initialization
  2. Static block initialization
  3. Lazy Initialization
  4. Thread Safe Singleton
  5. Bill Pugh Singleton Implementation
  6. Enum Singleton

 

Eager Initialization

This is the easiest way to create a singleton class. The instance of Singleton Class is created at the time of class loading.

The Singleton class is created at the time of class loading, instead of when it is required by the application. This is a major drawback in case the Singleton class is heavy and might not be required in the application.

package com.adevguide.java.designpatterns.singleton;

/**
 * @author pbhuite
 *
 */
public class EagerInitialization {

    // private construction so the class cannot be instantiated from outside also blocks inheritance
    private EagerInitialization() {
        System.out.println("A Singleton class is created using EagerInitialization.");
    }

    // private static final instance creation eagerly
    private static final EagerInitialization INSTANCE = new EagerInitialization();

    // public class for outside world to get the instance
    public static EagerInitialization getInstance() {
        return INSTANCE;
    }

}

 

If your singleton class is not using a lot of resources, this is the best approach to use. But in most of the scenarios, Singleton classes are created for resource hungry tasks such as File System, Database and Connections. We should avoid the instantiation until the client calls the getInstance method.
Also, this method doesn’t provide any options for exception handling.

 

Static Block Initialization

This implementation of the singleton is the same as eager initialization with an only difference as the addition of a static block. The instance of the class is created in a static block which provides exception handling options.

package com.adevguide.java.designpatterns.singleton;

/**
 * @author PraBhu
 *
 */
public class StaticBlockInitialization {

    private static StaticBlockInitialization instance;

    static {
        try {
            // private static final instance creation
            instance = new StaticBlockInitialization();
        } catch (Exception e) {
            System.out.println("Exception Occured" + e);
        }

    }

    // private construction so the class cannot be instantiated from outside also blocks inheritance
    private StaticBlockInitialization() {
        System.out.println("A Singleton class is created using StaticBlockInitialization.");
    }

    // public class for outside world to get the instance
    public static StaticBlockInitialization getInstance() {
        return instance;
    }

}

 

Lazy Initialization

This implementation of the singleton will create an instance of the class only when it is required in the application.

 

package com.adevguide.java.designpatterns.singleton;

/**
 * @author PraBhu
 *
 */
public class LazyInitialization {

    // private construction so the class cannot be instantiated from outside also blocks inheritance
    private LazyInitialization() {
        System.out.println("A Singleton class is created using LazyInitialization.");
    }

    // private static final instance creation lazy
    private static LazyInitialization instance;

    // public class for outside world to get the instance
    public static LazyInitialization getInstance() {
        if (null == instance) {
            instance = new LazyInitialization();
        }
        return instance;
    }

}

 

The above implementation works fine in the case of the single-threaded environment but when it comes to multithreaded systems, it can cause issues. If multiple threads are inside of the if loop at the same time, it will destroy the singleton pattern and both threads will get the different instances of the singleton class.

How is Java Pass by Value and Not by Reference [4 Examples]

Thread Safe Singleton

This implementation of the singleton creational design pattern is somewhat similar to Lazy initialization. The public global access method is synchronized to make the implementation thread-safe.

package com.adevguide.java.designpatterns.singleton;

/**
 * @author PraBhu
 *
 */
public class ThreadSafeSingleton {

    // private construction so the class cannot be instantiated from outside also blocks inheritance
    private ThreadSafeSingleton() {
        System.out.println("A Singleton class is created using ThreadSafeSingleton.");
    }

    // private static final instance creation
    private static ThreadSafeSingleton instance;

    // public class for outside world to get the instance
    public static synchronized ThreadSafeSingleton getInstance() {
        if (null == instance) {
            instance = new ThreadSafeSingleton();
        }
        return instance;
    }

}

 

Due to the use of synchronized keywords on method level, the performance of the implementation will be impacted. The synchronized method will be executed every time the instance is requested, while we only need to ensure thread safety in some initial threads when multiple instances could be created. To solve this, we can use the Double-Checked Locking Implementation.

package com.adevguide.java.designpatterns.singleton;

/**
 * @author PraBhu
 *
 */
public class ThreadSafeDoubleLocking {

    // private construction so the class cannot be instantiated from outside also blocks inheritance
    private ThreadSafeDoubleLocking() {
        System.out.println("A Singleton class is created using ThreadSafeDoubleLocking.");
    }

    // private static final instance creation
    private static ThreadSafeDoubleLocking instance;

    // public class for outside world to get the instance
    public static ThreadSafeDoubleLocking getInstance() {
        if (null == instance) {
            synchronized (ThreadSafeDoubleLocking.class) {
                if(null==instance)
                    instance = new ThreadSafeDoubleLocking();
            }
        }
        return instance;
    }

}

 

 

In this approach, the synchronized block is used inside if condition with an additional check to ensure that only one instance of the singleton class is created.

 

Note: With early versions of the JVM, synchronizing the whole method was generally advised against for performance reasons. But synchronized performance has improved a lot in new JVMs, so this is now a preferred solution.

 

Bill Pugh Singleton Implementation

This is the most optimized and preferred way of creating a Singleton class. Bill Pugh Singleton Implementation uses an inner static helper class to create an instance of the singleton class.

package com.adevguide.java.designpatterns.singleton;

/**
 * @author PraBhu
 *
 */
public class BillPughSingleton {

    // private construction so the class cannot be instantiated from outside also blocks inheritance
    private BillPughSingleton() {
        System.out.println("A Singleton class is created using BillPughSingleton.");
    }

    // private static final instance creation
    private static class InnerStaticHelperClass {
        private static final BillPughSingleton INSTANCE = new BillPughSingleton();
    }

    // public class for outside world to get the instance
    public static BillPughSingleton getInstance() {
        return InnerStaticHelperClass.INSTANCE;
    }
}

 

The private inner static class contains the instance of the singleton class. When the Singleton class is loaded, SingletonHelper class is not loaded into memory.

Only when someone calls the getInstance method, this class gets loaded and creates the Singleton class instance. This is the most widely used approach for Singleton class as it doesn’t require synchronization.

All About Java Regular Expressions Regex 2019

Enum Singleton

Enum can be used to implement Singleton design patterns as Java ensures that any enum value is instantiated only once in an Application. Since Java Enum values are globally accessible, so is the singleton.

package com.adevguide.java.designpatterns.singleton;

/**
 * @author PraBhu
 *
 */
public enum EnumSingleton {
    INSTANCE;
    
    public void getInstance() {
        //Perform some task here
    }

}

 

The drawback is that the enum type is somewhat inflexible; for example, it does not allow lazy initialization and enum values are always immutable.

 

When to use Singleton Creational Design Pattern?

  1. For resources that are expensive to create like XML Marshall content, database connection objects, etc.
  2. Classes that contain resources that are accessed in shared mode.
  3. It’s good practice to keep all loggers as Singleton which increases performance.
  4. Classes which provide access to configuration settings for the application.

 

Drawbacks of Singleton Creational Design Pattern

  1. Singleton class by design hides the clear dependencies of the project. This might create a big issue when the size of the project is huge.
  2. Singleton design is hard to unit test as a single instance cannot be mocked.
  3. Whenever a singleton class is deserialized, it will create a new instance of the class.
  4. As the static keyword is used while implementing singleton, there will be one instance of the class per class loader. If there are multiple class-loaders running under a single JVM, multiple instances will be created inside JVM.

Singleton Creational Design Pattern Example

Singleton design pattern is used in core java classes such as java.lang.Runtime, java.awt.Desktop.

 

Source Code

As always, you can find all the source code used in this tutorial in our GitHub repository.

GitHub Link