> For the complete documentation index, see [llms.txt](https://jrp.gitbook.io/notes/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://jrp.gitbook.io/notes/design-pattern/creational-singleton.md).

# Creational - Singleton

<div data-with-frame="true"><figure><img src="/files/BUs2v3FFdnXo5197rmHN" alt=""><figcaption></figcaption></figure></div>

Imagine there’s only **one cookie jar** in your house. No matter how many times you ask for a cookie, your parents always send you to the same jar—**the ONE and ONLY COOKIE JAR**. If all your friends come over, everyone has to share from the same jar too. No matter what, there’s just one magic cookie jar!

If anyone tries to sneak a second cookie jar into the house… the cookie police (your parents!) say “Nope! Only one allowed!”

So, a singleton in computer code is just like this: there can **never** be two cookie jars, and everyone always gets cookies from the **one special jar**!

Singleton is simply a class which is instatiated once per JVM initialisation.There are many ways to achieve it.

### **Eager initialisation**

```java
public class EagerSingleton {
	// instance created immediately
	private static volatile EagerSingleton instance = new EagerSingleton();

	// private constructor
	private EagerSingleton() {
	}

	public static EagerSingleton getInstance() {
		return instance;
	}
}
```

Advantage:

* Rely on JVM to create singleton instance
* JVM guaraentees that the instance will be created before any thread access the instance variable.
* inherently thread-safe

Drawback:

* Instance is created irrespective of it is required in runtime or not
* This wastes resources&#x20;
  * if singleton instance creation is a heavy process&#x20;
  * or instance is never used by the client application

Then what's the better approach ?

### **Lazy Initialization**

**Lazy initialization** is a concept where the Singleton instance is **not created** until it is needed (on the first call to `getInstance()`), rather than at class loading time.

```java
public final class LazySingleton {
	private static volatile LazySingleton instance = null;

	// private constructor
	private LazySingleton() {
	}

	public static LazySingleton getInstance() {
		if (instance == null) {  //T1 and T2 at same time
			synchronized (LazySingleton.class) { // suppose T1 enters, then T2
				instance = new LazySingleton(); // inst1, inst2
			}
		}
		return instance;
	}
}
```

Drawback:

Suppose there are two threads T1 and T2. Both comes to create instance and execute `instance==null`, now both threads have identified instance variable to null thus assume they must create an instance. They sequentially goes to synchronized block and create the instances. At the end, we have two instances in our application.

Then what's the solution?

**Double Checked Locking**

```java
public class LazySingleton {
	private static volatile LazySingleton instance = null;

	// private constructor
	private LazySingleton() {
	}

	public static LazySingleton getInstance() {
		if (instance == null) { // Both T1 and T2 at same time
			synchronized (LazySingleton.class) { // Suppose T1 enters first
				// Double check 
				if (instance == null) { 
					instance = new LazySingleton(); // inst1
				}
			} // Turn for T2
		}
		return instance;
	}
}
```

Please ensure to use **Volatile** keyword with instance variable otherwise you can run into **out of order** write error scenario, where reference of instance is returned before actually the object is constructed i.e. JVM has only allocated the memory and constructor code is still not executed. In this case, your other thread, which refer to uninitialized object may throw null pointer exception and can even crash the whole application.

Though it's a popular solution, but there is an alternative approach to get rid of synchronization overhead.

**Bill pugh Solution**

```java
// Instead of intializing immediately, 
//instance will be created using an inner class
public class BillPughSingleton {
	// private constructor
	private BillPughSingleton() {}
	
	// inner class
	private static class LazyHolder {
		private static final BillPughSingleton INSTANCE = new BillPughSingleton();
	}

	public static BillPughSingletongetInstance() {
		return LazyHolder.INSTANCE;
	}
}
```

Advantage:

* Lazy Initialization : As you can see, until we need an instance, the LazyHolder class will not be initialized until required and you can still use other static members of BillPughSingleton class.
* Thread Safety : This method is *inherently thread-safe* without requiring synchronized blocks.&#x20;

<mark style="color:purple;">Class loading in Java is thread-safe by default, so the instance creation is safe in multithreaded environments.</mark>

* No Synchronization Overhead: There is no performance cost of synchronization in the `BillPughSingletongetInstance()` method.

Now, it seems, we are good with singleton pattern using Lazy Initialization. If you think so, then check below code&#x20;

```java
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;

public class ClientHackerOne {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        createMultipleInstanceUsingSerialization();
    }
    // similar code for bill pugh solution as well
    private static void createMultipleInstanceUsingSerialization() throws IOException, ClassNotFoundException {
        DLazySingleton instance1 = DLazySingleton.getInstance();
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(Files.newOutputStream(Paths.get("tmp.obj")));
        objectOutputStream.writeObject(instance1);
        objectOutputStream.close();

        ObjectInputStream objectInputStream = new ObjectInputStream(Files.newInputStream(Paths.get("tmp.obj")));
        DLazySingleton instance2 = (DLazySingleton) objectInputStream.readObject();
        objectInputStream.close();

        System.out.println("Object1 : " + instance1.hashCode()); //1775282465
        System.out.println("Object2 : " + instance2.hashCode()); //1604839423

        File file = new File ("tmp.obj");
        file.deleteOnExit();

    }
}

```

You can see, the hashcode of the objects are different. This means the objects are different. Hence Singleton pattern is violated.

To solve this, use implement `readResolve()`  method in LazySingletonClass

```java
//inside Singleton class
protected Object readResolve() {
    return instance;
}
//This method ensures that during deserialization, 
//the existing singleton instance is returned rather than creating a new object.
```

Now you can run `ClientHackerOne` class to check the hashcodes of the objects.

Now, I think, we are good enough for Singleton Pattern.&#x20;

Wait!!! Check below class

```java
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class ClientHackerTwo {
    public static void main(String[] args) throws InvocationTargetException, InstantiationException, IllegalAccessException {
        createMultipleInstanceUsingReflection();
    }

    private static void createMultipleInstanceUsingReflection() throws InvocationTargetException, InstantiationException, IllegalAccessException {
        Constructor<?>[] declaredConstructors = DLazySingleton.class.getDeclaredConstructors();
        Constructor<?> constructor = declaredConstructors[0];
        constructor.setAccessible(true);

        DLazySingleton instance1 = (DLazySingleton) constructor.newInstance();
        DLazySingleton instance2 = DLazySingleton.getInstance();

        System.out.println("Object1 : " + instance1.hashCode()); //1067040082
        System.out.println("Object2 : " + instance2.hashCode()); //1706377736

        
    }
}
```

Again, the objects are with different hashcodes.

To solve this use Enum

**Enum**

provide implicit support for thread safety and only one instance is guaranteed.Recommended in `Effective Java`

```java
public enum EnumSingleton {
	INSTANCE;
	public void someMethod(String param) {
		// some class member
	}
}
```

To Test the singleton pattern use below code in `ClientHackerTwo`

```java
EnumSingleton singleton1 = EnumSingleton.INSTANCE;
EnumSingleton singleton2 = EnumSingleton.INSTANCE;

System.out.println("Object1 : " + singleton1.hashCode()); //1804094807 
System.out.println("Object2 : " + singleton2.hashCode()); //1804094807
```

&#x20;<mark style="color:purple;background-color:$info;">A classic example of the singleton pattern in the JDK is the</mark> <mark style="color:purple;background-color:$info;"></mark><mark style="color:purple;background-color:$info;">**java.lang.Runtime**</mark> <mark style="color:purple;background-color:$info;"></mark><mark style="color:purple;background-color:$info;">class.</mark>

* <mark style="color:purple;background-color:$info;">Only one Runtime object can exist in a Java application; you can’t create another instance.</mark>
* <mark style="color:purple;background-color:$info;">You get the single instance by calling</mark> <mark style="color:purple;background-color:$info;"></mark><mark style="color:purple;background-color:$info;">`Runtime.getRuntime()`</mark><mark style="color:purple;background-color:$info;">.</mark>
* <mark style="color:purple;background-color:$info;">This object lets you interact with the environment in which the application is running (like running external processes, reading environment variables, etc.).</mark>

```java
Runtime runtime = Runtime.getRuntime();
```

**Conclusion**

Singleton Pattern can be achieved by 3 ways&#x20;

* Eager Initialization  - JVM way, thread safe
* Lazy Initialization - Lazily initialized,&#x20;
  * go for double checking approach with readResolve()
  * or go for bill pugh solution with readResolve()
* Enum for simple usecases (recommended)
