Singleton Pattern Examples and Implementation

Implementation of Singleton Design pattern

 

To implement a 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.

 

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

 

Let’s put them in Action.

 

 

Approach-1 

 

Eager Initialization

 

In eager initialization, the instance of the singleton class is created at the time of class loading. The drawback to eager initialization is that the method is created even though the client application might not be using it. Here is the implementation of the static initialization singleton class

 

public class EagerInitializedSingleton {

 

private static final EagerInitializedSingleton instance = new EagerInitializedSingleton();

 

  // private constructor to avoid client applications using the constructor

 

  private EagerInitializedSingleton(){}

 

  public static EagerInitializedSingleton getInstance() {

 

    return instance;

 

  }

 

}

 

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

 

 

Approach-2

 

Static Block Initialization

 

Static block initialization implementation is similar to eager initialization, except that instance of the class is created in the static block that provides the option for exception handling.

 

public class StaticBlockSingleton {

 

private static StaticBlockSingleton instance;

 

private StaticBlockSingleton(){}

 

// static block initialization for exception handling

static {

try {

instance = new StaticBlockSingleton();

} catch (Exception e) {

throw new RuntimeException("Exception occurred in creating singleton instance");

}

}

 

public static StaticBlockSingleton getInstance() {

return instance;

}

}

 

Both eager initialization and static block initialization create the instance even before it’s being used and that is not the best practice to use.

 

Approach-3

 

Lazy Initialization

 

Lazy initialization method to implement the singleton pattern creates the instance in the global access method. Here is the sample code for creating the singleton class with this approach:

 

public class LazyInitializedSingleton {

 

    private static LazyInitializedSingleton instance;

 

    private LazyInitializedSingleton(){}

 

    public static LazyInitializedSingleton getInstance() {

        if (instance == null) {

            instance = new LazyInitializedSingleton();

        }

        return instance;

    }

}

 

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

 

Approach-4

 

Thread-safe Singleton

 

A simple way to create a thread-safe singleton class is to make the global access method synchronized so that only one thread can execute this method at a time. Here is a general implementation

 of this approach:

 

public class ThreadSafeSingleton {

    private static ThreadSafeSingleton instance;

    private ThreadSafeSingleton(){}

    public static synchronized ThreadSafeSingleton getInstance() {

        if (instance == null) {

            instance = new ThreadSafeSingleton();

        }

        return instance;

    }

The preceding implementation works fine and provides thread-safety, but it reduces the performance because of the cost associated with the synchronized method, although we need it only for the first few threads that might create separate instances. To avoid this extra overhead every time, double-checked locking principle is used. In this approach, the synchronized block is used inside the if condition with an additional check to ensure that only one instance of a singleton class is created. The following code snippet provides the double-checked locking implementation:

 

public static ThreadSafeSingleton getInstanceUsingDoubleLocking() {

    if (instance == null) {

        synchronized (ThreadSafeSingleton.class) {

            if (instance == null) {

                instance = new ThreadSafeSingleton();

            }

        }

    }

    return instance;

}

 

How Singleton Pattern Break?

 

·       One of the easiest way one can break singleton pattern is via Reflection API, Reflection API has the power to modify the behaviour of methods, classes, and interfaces at runtime.

·       One can say one can get the blueprint of class via Reflection API. So, the basic idea to break Singleton Design pattern via Reflection is one can get access to the private constructor of class make it public runtime and can create another instance of it.

 

How to overcome it?

 

·      We can use Enum to overcome it as whenever we declare enum those will be static values by default, so we can directly call them.

·       Another thing is whatever the constructors are called we as developer cannot call constructor JVM itself calls it so we are safe there as well...!!

·       And it’s also thread Safe.


 

Example to break Singleton Pattern via Reflection.

 

class Singleton {

    // public instance initialized when loading the class

    public static Singleton instance = new Singleton();

 

    private Singleton()

    {

        // private constructor

    }

}

 

public class BreakSingleton {

 

    public static void main(String[] args)

    {

        Singleton instance1 = Singleton.instance;

        Singleton instance2 = null;

        try {

            Constructor[] constructors

                = Singleton.class.getDeclaredConstructors();

            for (Constructor constructor : constructors) {

                // Below code will destroy the singleton

                // pattern

                constructor.setAccessible(true);

                instance2

                    = (Singleton)constructor.newInstance();

                break;

            }

        }

 

        catch (Exception e) {

            e.printStackTrace();

        }

 

        System.out.println("instance1.hashCode():- "

                           + instance1.hashCode());

        System.out.println("instance2.hashCode():- "

                           + instance2.hashCode());

    }

}

 

Example to Fix Singleton Pattern


public enum SingletonSafe {

INSTANCE;

public void getInformation() {

System.out.println("Hello World");

}


}


public class SingletonPattern {


public static void main(String[] args) {

SingletonSafe.INSTANCE.getInformation();

}

Comments

Popular posts from this blog

State space search / blocks world problem by heuristic approach /TIC TAC TOE

Navigation in Vaadin.

Drag and drop items from one Grid to another