Back to blogs

Let’s talk Singleton

Jun 14, 2019

by Bargunan S

Singleton pattern is one of the GOF (Gangs of Fiur) design pattern.  It’s one of the basic and most known creational design pattern, yet lot misunderstood in implementing it. Let’s delve deeper into what is Singleton Pattern is and how to create an effective singleton in Java. Since there exists multiple implementations for Singleton pattern, let’s see what are the merits of choosing one Singleton design over the other. 

What is Java Singleton Design Pattern? 

  • The Singleton Design Pattern ensures that the instance of a particular class is created only one throughout the Java Virtual Machine by providing a check on the initialization. 
  • It also provides a unique global access point to the object so that each subsequent call to the access point returns only that particular object. ie no new instances are created for subsequent calls. 
  • Singleton also guarantees control of a resource 

Why do we need Singleton? Or when to use Singleton? 

On the design perspective, some scenarios require only one instance of a class to be created.   

For example,  

  • Facade objects are often Singletons because only one Facade object is required.  
  • Creating multiple loggers in an application is a costly operation, so making the loggers singleton reduces the performance overhead 
  • One-time Configurations can be encapsulated into Singletons eg. Driver objects or database connection string. 
  • Caching play an important role in reducing the server calls, by sending the same result, so designing the Caching resources singleton, makes the same resource available for all the future calls. 
  • Other design pattern like Prototype, Abstract Factory, Façade and Builder also employs Singleton. 

How to implement Java Singleton? 

Steps to create a Singleton Class:  

There are multiple approaches in implementing the Singleton. One method has advantage over the other. But let’s see the steps common to them in creating a Singleton Class. 

  1. Make the constructor of the class private, so that the instantiation outside the class can be restricted. 
  2. Create a private static variable of type of the same class, which will be the only instance of the class. 
  3. Write a public static method whose, return type will be of the same class and which will instantiate the class only once and return that instance. This method will be the global point of access to the outside world to access the Singleton instance of the class. 

Code Snippet Of a minimal Singleton Design 

public class FileLogger { 

       private static FileLogger logger

       // prevents instantiation from outside class 

       private FileLogger() { 

       } 

       // Global point of access 

       public static FileLogger getFileLogger() { 

              if (logger == null) { 

                     logger = new FileLogger(); 

              } 

              return logger

       } 

Types of Singleton in Java. 

There are multiple approaches in OOPS to design a class Singleton. Based on the need, following are the types of Singleton. 

  1. Eagerly initialized Singleton 
  2. Lazily initialized Singleton 
  3. Static block initialized Singleton 
  4. Bill pugh or On Demand Holder Singleton 
  5. Thread safe Singleton 
  6. Serialization safe Singleton 
  7. Reflection safe Singleton 
  8. Clone safe Singleton 
  9. Enum Singleton 
  10. Weak Malleable Singleton 
  11. Soft Malleable Singleton 


Eagerly initialized Singleton 

In case of eagerly initialized singleton, the instance of the class is created at the time of class loading.  This is the simplest one but has lot of disadvantages. 

Merits: 

  • Thread safe. 
  • Simple to create. 

Demerits: 

  • The instance is created even before the client could use it. 
  • Prone to Reflection i.e multiple instances can be created by using Reflection. 
  • Prone to Cloning i.e when cloned returns new instances. 

Code Snippet.

public class EagerlyInitializedSingleton { 

       private static Optional<EagerlyInitializedSingleton> INSTANCE = Optional 

                     .ofNullable(new EagerlyInitializedSingleton()); 

       private EagerlyInitializedSingleton() { 

       } 

       public static Optional<EagerlyInitializedSingleton> getInstance() { 

              return INSTANCE

       } 


Lazily initialized Singleton 

As the name describes, the instance of the class is created only when required or the call is made to the getInstance() Method. 

Merits: 

  • Lazy initialization with good performance. 

Demerits: 

  • Not Thread Safe. In a multi-threaded environment the singleton is destroyed. 
  • Prone to Reflection i.e multiple instances can be created by using Reflection. 
  • Prone to Cloning i.e when cloned returns new instances. 

Code Snippet.

public class LazilyInitializedSingleton { 

          private static Optional<LazilyInitializedSingleton> INSTANCE = Optional.empty(); 

       private LazilyInitializedSingleton() { 

       } 

       public static Optional<LazilyInitializedSingleton> getInstance() { 

              if (!INSTANCE.isPresent()) { 

                 INSTANCE = Optional.ofNullable(new LazilyInitializedSingleton()); 

              } 

              return INSTANCE

       } 


 Static block initialized Singleton 

Here the instance is initialized in the static block. 

Merits: 

  • A runtime Exception can be thrown in case of issues in creation of the Singleton instance. 
  • Thread Safe. 

Demerits: 

  • It’s similar to eagerly initialized Singleton approach; hence the instance is created even before the client could use it. 
  • Prone to Reflection i.e multiple instances can be created by using Reflection. 
  • Prone to Cloning i.e when cloned returns new instances 

Code Snippet.

public class StaticBlockSingleton { 

       private static StaticBlockSingleton INSTANCE

       private StaticBlockSingleton() { 

       } 

       static { 

              try { 

                     INSTANCE = new StaticBlockSingleton(); 

              } catch (Exception e) { 

                     throw new RuntimeException(“Exception in creating singleton instance”); 

              } 

       } 

       public static StaticBlockSingleton getInstance() { 

              return INSTANCE

       } 


Bill pugh or On Demand Holder Singleton 

Bill Pugh’s “On demand Holder” approach of creating Singleton class is widely used for its ease in solving Java memory model issues and for lazy loading. 

This approach uses static block but in a different way by employing a static inner class which will act as an on-demand holder.   

Merits: 

  • Lazy initialization with good performance 
  • Easy to understand and implement. 
  • Thread Safe. 

Demerits: 

  • Prone to Reflection i.e multiple instances can be created by using Reflection. 
  • Prone to Cloning i.e when cloned returns new instances 

Code Snippet.

 public class BillPughSingleton { 

       private BillPughSingleton() { 

       } 

       private static class SingletonHolder { 

        private static final BillPughSingleton INSTANCE = new BillPughSingleton(); 

       } 

       public static BillPughSingleton getInstance() { 

              return SingletonHolder.INSTANCE

       } 


Thread safe Singleton 

Since JVM being a multi-threaded platform, it’s a good practice to design the singleton for concurrency safety.   

To make the lazily initialized singleton thread safe, the easier or probably the naïve way is to make the getInstance() method  synchronized. 

Code Snippet.

public class SingleThreadSingleton { 

       private static Optional<SingleThreadSingleton> INSTANCE

       private SingleThreadSingleton() { 

       } 

       public static synchronized Optional<SingleThreadSingleton> getInstance() { 

              if (!INSTANCE.isPresent()) { 

                     INSTANCE = Optional.ofNullable(new SingleThreadSingleton()); 

              } 

              return INSTANCE

       } 

Merits: 

Lazy initialization 

  • Thread Safe. 

Demerits: 

  • Making the getInstanc() methods synchronized slows down the performance, since the sequential access is given for threads to access the Singleton instance. In a multi-threaded environment, it would have a huge impact on the performance. 
  • Prone to Reflection i.e multiple instances can be created by using Reflection. 

To reduce that performance issue every time, there is another approach called “Double-Checked locking”. 

  Code Snippet.

public class MultiThreadedSingleton { 

      private static Optional<MultiThreadedSingleton> INSTANCE = Optional.empty(); 

       private MultiThreadedSingleton() { 

       } 

       public static Optional<MultiThreadedSingleton> getInstance() { 

              if (!INSTANCE.isPresent()) { 

                     synchronized (INSTANCE) { 

                           if (!INSTANCE.isPresent()) 

                     INSTANCE = Optional.ofNullable(new MultiThreadedSingleton()); 

                     } 

              } 

              return INSTANCE

       } 

Here instead of synchronizing the whole method, the critical section is synchronized. Also, an additional null check is made inside the if conditional to make sure, the singleton is concurrent safe for access. 

Merits: 

  • Concurrent safe. 
  • Less overhead in multi-threaded environment. 
  • Lazy instantiation of the instance. 

Demerits: 

  • Prone to Reflection i.e multiple instances can be created by using Reflection. 
  • Prone to Cloning i.e when cloned returns new instances 


Serialization safe Singleton 

 At times, the Singleton must be serialized i.e its state has to be saved / persisted and retrived back or has to be sent over the network. To achieve this, the  Singleton Class must implement the marker interface Serializable.

This serializable Singleton has a problem, when the reverse process of deserialization is applied. The deserialization process creats new instances of the Singleton class.

The destruction of Singleton for the Serialized class can be prevented by implementing the readResolve method, a class can directly control the types and instances of its own instances being deserialized. The method is defined as follows:

            ANY-ACCESS-MODIFIER Object readResolve()

                         throws ObjectStreamException;

The readResolve method would be implemented to determine if that SerializedSingleton was already defined and substitute the preexisting equivalent SerializedSingleton  object to maintain the identity constraint. In this way the uniqueness of SerializedSingleton  objects can be maintained across serialization.

Code snippet of Serialization Safe Singleton.  

public class SerializedSingleton implements Serializable { 

       private static final long serialVersionUID = 1L; 

       private SerializedSingleton() { 

       } 

       private static class SingletonHolder { 

          private static final SerializedSingleton INSTANCE = new SerializedSingleton(); 

       } 

       public static SerializedSingleton getInstance() { 

              return SingletonHolder.INSTANCE

       } 

       public Object readResolve() { 

              return getInstance(); 

       } 


Reflection safe Singleton 

Reflection API in Java is commonly used by programs which require the ability to examine or modify the runtime behavior of applications running in the Java virtual machine. Aving described the power of Reflection API, it can break the Singleton class by changing the access level of constructor from private to public.

constructor.setAccessible(true); 

Now as many as possible new instances can be created from the Singleton Class.

Code Snippet.

public class Reflectiontest {

       public static void main(String[] args) {

              EagerlyInitializedSingleton rSingleton1 = EagerlyInitializedSingleton.getInstance().get();

              try {

                     Class clazz = Class.forName(“com.pattern.creational.singleton.EagerlyInitializedSingleton”);

                     Constructor<?> constructor = clazz.getDeclaredConstructor();

                     constructor.setAccessible(true);

                     EagerlyInitializedSingleton rSingleton2 = (EagerlyInitializedSingleton) constructor.newInstance();

       System.out.println(“First Instance Hashcode ==>” + rSingleton1.hashCode());

       System.out.println(“Second Instance Hashcode==>” + rSingleton2.hashCode());

              } catch (Exception e) {

              }

       }

}

Now the hashcodes are different, implying that the singleton is no more Sigleton.

First Instance Hashcode ==>366712642

Second Instance Hashcode==>1829164700

There are two ways in which the Reflection API breaking the Singleton can be prevented.

  1. Check instantiation in the constructor.
    1. Using enum to design Singleton.

Code Snippet.

private EagerlyInitializedSingleton() {

              if (!INSTANCE.isPresent()) {

               throw new IllegalStateException(“Singleton already constructed”);

           }

       }

But again, this method is nt totally fool proof, since  if someone tries to mess around with reflection to access private members, they may be able to set the field to null themselves.

The fool proof way against Reflection is to use enum to create Singleton.

Code Snippet.

public enum EnumSingleton {

       INSTANCE;

}

To be continued…