Thursday, 10 March 2016

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 is an EJB

Singleton Design Pattern


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

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.



@Command 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; } }

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).

Singleton is an EJB

http://www.mastertheboss.com/javaee/ejb-3/singleton-ejb-tutorial

2 comments:

  1. Excellent writing (Y). The details and questions you have mentioned are really useful. Keep it up.

    Have you written about other Design patterns as well ?

    ReplyDelete
    Replies
    1. http://java91.blogspot.in/2015/09/design-patterns-in-java.html

      Delete