Singleton Design Pattern in Java

In this article, we will discuss :
 
– What is Singleton design pattern ?
– How to implement Singleton design pattern in java ?
– Effects of multithreading on singleton pattern
– Implementing Double checked locking for singleton
– Eager instantiation of singleton
– Ways of breaking singleton
– Uses of Singleton pattern
– Singleton pattern in Java EE
– Singleton as Anti-pattern
 

Singleton Design Pattern

 
The Singleton pattern ensures that a class has only one instance and provides a global point of access to it.
 
singleton pattern
 

Standard Singleton implementation

 
To ensure the class has only one instance, we mark the constructor has private. So, we can only instantiate this class from within the class.
 
We create a static variable that will hold the instance of the class.
 
Then, we create a static method that provides the instance of the singleton class. This method checks if an instance of the singleton class is available. It creates an instance, if its not available; Otherwise, it returns the available instance.
 

public class Singleton {
  
  private static Singleton instance;

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

 

Problem with the standard implementation code above

 
The standard singleton implementation code works fine in Single threaded environment.
 
But in multithreaded environment, the getInstance() code breaks :
 

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

 
If two threads enter the if condition at the same time, then two instances of Singleton will be created.
 

Handling Multithreading issue with standard singleton implementation

 
We can add synchronized keyword to the getInstance method signature and it would make the method synchronized. So, only one thread can access it at a time.
 

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

 
This solves the multithreading issue. But it is slow since only one thread can access getInstance() method at a time.
 
We can use following approaches for this :
 

1 : Double checked locking

 
In this approach, we first check if the instance is created. If not, we synchronize.
 

public class Singleton {

  private static Singleton instance;

  private Singleton() {
  }

  public static Singleton getInstance() {
    //first check if instance is available
    if (instance == null) {
      //if instance not available, enter synchronized block to create
      synchronized (Singleton.class) {
        if (instance == null) {
          instance = new Singleton();
        }
      }
    }
    return instance;
  }
}

 
This is an approach to handle multithreading issues with the standard implementation. However, this approach has issues as well. Read more about this in the comments section before using this.

 

2 : Eager instance creation

 
We can choose to create the instance of Singleton class when the class is loaded.
 

public class EagerSingleton {
  //create instance eagerly
  private static EagerSingleton instance = new EagerSingleton();

  private EagerSingleton() {}
  
  public static EagerSingleton getInstance(){
    return instance;//just return the instance
  }
}

 

3 : Bill Pugh Singleton

 
This solution is considered better as it performs singleton instantiation when getInstance() is called.
 

public class BillPughSingleton {
 private BillPughSingleton(){}

private static class SingletonHelper{
 private static final BillPughSingleton INSTANCE = new BillPughSingleton();
 }

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


Thanks Karl for providing this code in comments section.
 

4 : Creating Singleton using Enum

 
Enum is thread safe. We can implement Singleton through Enum so that the singleton will have only one instance even in a multithreaded environment.

public enum EnumSingleTon {
  INSTANCE;

  // add sinlgeton methods
  public void method() {
    System.out.println("SingleTon Method");
  }
}

public class TestEnumSingleton {

  public static void main(String[] args) {
    EnumSingleTon.INSTANCE.method();
  }

}


 
Using enums protects against deserialization and reflection. Also, Enum singletons are lazily initialized.

Enum based singleton is considered the best way to implement singletons. (Refer : Effective Java by Joshua Bloch)
 

Breaking Singleton questions you may get in interviews

 
Even though we avoided multiple instance creation of singleton class by using Double checked locking or Eager instance creation, instances can still be created by :
– cloning
– reflection
– Deserialization
– Sub-classing singleton class
 

How to avoid Singleton instance creation by cloning ?

 
We can create a copy of an object using clone() method.
 
To avoid creating a clone of our singleton class, we can do the following :
 
– Implement Cloneable interface

– Override the clone() method and throw CloneNotSupportedException from it.

 

How to avoid Singleton class instance creation through Reflection ?

 
To avoid instance creation through reflection, throw an exception from constructor if it already has an instance.
 

private Singleton() {
    if( Singleton.instance != null ) {
       throw new InstantiationError("Cannot create instance Singleton through reflection");
     }
}

 

How to avoid singleton instance creation during deserialization ?

 
Avoid multiple singletons during deserialization using readResolve().
 

protected Object readResolve() {return instance;}

 

How to avoid a subclass creating singleton instance ?

 
If you just provide a private constructor, a subclass cannot instantiate it to create another instance. This is because the super constructor won’t be visible to the child class.
 

Uses of Singleton Design Pattern

 

Logger

 
Singleton pattern is a good option for the Logger class when we want to create one log file with the logged messages. If we have more than one instances of Logger in the application, a new log will be created with every instance.
 

Cache

 
We can use Singleton pattern to implement caches as that provides a single global access to it.
 

Implementing Singleton Pattern in Java EE

 
In Java EE, just by adding @Singleton annotation to a class, you can turn it into a singleton bean.
 

import javax.ejb.Singleton;

@Singleton
public class SingletonBean {

}

 
The @Singleton annotation marks the class as a singleton EJB, and the container handles creation and usage of the single instance.
 

Why singleton pattern is considered an Anti-pattern ?

 
– Singletons aren’t easy to handle with unit tests. You can’t control their instantiation and they may retain state across invocations.
 
Frameworks such as Spring control the lifecycle of their objects and often create singletons, but these objects are injected into their dependent objects by the framework. Thus the codebase itself doesn’t treat the objects as singletons.
 
– In multithreaded environment, access to the singleton object may have to be guarded (e.g. via synchronisation).
 
 

Further Reading

 

DoubleCheckedLocking is broken

Simply Singleton

Why Singletons Are Controversial

Factory pattern

Abstract Factory Pattern

Enterprise Design Patterns

Also, refer the comments section for some nice additions.
 

© 2016 – 2017, https:. All rights reserved. On republishing this post, you must provide link to original post

7 comments

  1. […] Reference : Singleton Design Pattern in Java […]

  2. […] Further Reading: Singleton Realtime Examples Implementaing Singleton in C# Singleton Implementation in Java […]

  3. […] Further Reading: Singleton Realtime Examples Implementaing Singleton in C# Singleton Implementation in Java […]

  4. Can you give some more examples of where Singleton classes are used ? like in any Business logic examples ?

  5. Double-checked locking is known to be broken:
    http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html

    Using enums protects against deserialization and reflection, hence enum based singletons are considered the best practics (AFAIK).

  6. package com.journaldev.singleton;
    public class BillPughSingleton {
    private BillPughSingleton(){}

    private static class SingletonHelper{
    private static final BillPughSingleton INSTANCE = new BillPughSingleton();
    }

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

  7. I tried to do the same in C#. I left out deserialization. Here is the result:

    public class Singleton
    {
        private static Singleton instance;
        public static Singleton GetInstance()
        {
            lock (typeof(Singleton))
            {
                if (instance == null)
                {
                    instance = new Singleton();
                }
            }
            return instance;
        }
        private Singleton()
        {
            if (instance != null)
            {
                throw new Exception("Cannot create singleton instance through reflection");
            }
        }
        protected object MemberwiseClone()
        {
            throw new Exception("Cloning a singleton object is not allowed");
        }
    }
    

Leave a Reply.. code can be added in <code> </code> tags

%d bloggers like this: