What is singleton?

Singleton

Steps to make singleton

  1. private Constructor

  2. static getInstance method

  3. synchronized

  4. override clone() method

disadvantage of Singleton

  1. it carries state of object

  2. it prevents dependency injection and cannot be unit tested

https://www.journaldev.com/1377/java-singleton-design-pattern-best-practices-examples

  • Singleton pattern restricts the instantiation of a class and ensures that only one instance of the class exists in the java virtual machine.

  • The singleton class must provide a global access point to get the instance of the class.

  • Singleton pattern is used for logging thread pool, drivers objects, caching and

  • Singleton design pattern is also used in other design patterns like Abstract Factory Builder, Prototype, Facade etc.

  • Singleton design pattern is used in core java classes also, for example

    java.lang.Runtime,java.awt.Desktop

To implement Singleton pattern, we have different approaches but all of them have 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 outer world to get the instance of the singleton class.

Eager initialization

In eager initialization, the instance of Singleton Class is created at the time of class loading, this is the easiest method to create a singleton class but it has a drawback that instance is created even though client application might not be using it.

Static block initialization

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

Lazy Initialization

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

not thread safe

Thread Safe Singleton

The snippetsynchronized(X.class)uses the class instance as a monitor. As there is only one class instance (the object representing the class metadata at runtime) one thread can be in this block.

Withsynchronized(this)the block is guarded by the instance. For every instance only one thread may enter the block.

synchronized(X.class)is used to make sure that there is exactly one Thread in the block. synchronized(this)ensures that there is exactly one thread per instance. If this makes the actual code in the block thread-safe depends on the implementation. If mutate only state of the instancesynchronized(this)is enough.

import java.util.*;

public class ThreadSafeSingleton{

    private static ThreadSafeSingleton instance;

    private ThreadSafeSingleton(){}

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

    public static ThreadSafeSingleton getInstanceUsingDoubleLocking(){
        if(instance==null){
            synchronized(ThreadSafeSingleton.class){//synchronized  .class
                if(instance==null) instance = new ThreadSafeSingleton();
            }
        }
        return instance;
    }


}

Bill Pugh Singleton Implementation

Notice the private inner static class that contains the instance of the singleton class. When the singleton class is loaded,SingletonHelperclass is not loaded into memory and 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.

public class BillPughSingleton {

    private BillPughSingleton(){}

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

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

Serialization and Singleton

import java.io.Serializable;

public class SerializedSingleton implements Serializable{

    private static final long serialVersionUID = -7604766932017737115L;

    private SerializedSingleton(){}

    private static class SingletonHelper{
        private static final SerializedSingleton instance = new SerializedSingleton();
    }

    public static SerializedSingleton getInstance(){
        return SingletonHelper.instance;
    }

}

The problem with above serialized singleton class is that whenever we deserialize it, it will create a new instance of the class.

So it destroys the singleton pattern, to overcome this scenario all we need to do it provide the implementation of

readResolve()method.

protected Object readResolve(){
    return getInstance();

}

Enum Singleton(best method of making singletons in Java.)

Since Java Enum values are globally accessible, so is the singleton. The drawback is that the enum type is somewhat inflexible; for example, it does not allow lazy initialization.

eg0:

public enum EnumSingleton {

    INSTANCE;

    public static void doSomething(){
        //do something
    }
}

eg1:

enum Singleton{
    Instance;
    private final Connection connection;

    Singleton(){
        connection = DB.getConnection();
    }
    public static Singleton getInstance(){
        return Instance;
    }

    public Connection getConnection(){
        return connection;
    }
}

Problems with enum as singleton

  • enums do not support lazy loading

  • Though it's very very rare but if you changed your mind and now want to convert your singleton to multi-ton, enum would not allow this.

Steps to make singleton

  • private Constructor

  • static getInstance method

  • synchronized

  • override clone() method

Disadvantage of Singleton

  • it carries state of object

  • it prevents dependency injection and cannot be unit tested

eg:

public class Singleton{
    private static Singleton instance;
    private static synchronized Singleton getInstance(){
        if(instance==null){
            instance = new Singleton();
        }
        return instance;
    }
    @Override
    public Object clone() throws CloneNotSupportedException(){
        throws new CloneNotSupportedException();
    }
}

https://stackoverflow.com/questions/30671534/why-enum-singleton-are-serialization-safe

Why Enum singleton are serialization safe?

Serialization treats enums specially. Basically, it stores only a reference to its class and the name of the constant. Upon deserialization, this information is used to lookup the existing runtime object of the enum type.

Thus, if you deserialize the enum constant within the same runtime, you will get the same runtime instance you have serialized.

However, when deserializing in another JVM, the hashcode might be different. But having the same hashcode is not a required criteria for singletons. The important point is to never have another instance of the class and this is guaranteed as the serialization implementation will never create an instance of an enum type but only lookup existing constants.

https://dzone.com/articles/java-singletons-using-enum

Last updated

Was this helpful?