In Java the Singleton pattern will ensure that there is only one instance of a class is created in the Java Virtual Machine. It is used to provide global point of access to the object. In terms of practical use Singleton patterns are used in logging, caches, thread pools, configuration settings, device driver objects.
Table of content
- Definition
- Advantage
- Structure
- UML Diagrams
- Implementation ExampleLazy initialisation
- Eager initialisation
- Static block initialisation
- Thread safe singleton
- Bill Pugh singleton
- enum singletons
- Using Reflection to Destroy Singleton Patterns
- Preserve single instance – clone
- Serialisation vs deserialisation
- Usage of singletons
- FAQs
Definition
Singleton Pattern says that just “define a class that has only one instance and provides a global point of access to it”.
Singleton is categorised under creational design patterns.
In this article we are going to take a deeper look into the usage of the Singleton pattern. It is one of the most simple design pattern in terms of the modelling but on the other hand this is one of the most controversial pattern in terms of complexity of usage.
Advantage
Saves memory because object is not created at each request. Only single instance is reused again and again.
This has advantages in memory management, and for Java, in garbage collection. Moreover, restricting the number of instances may be necessary or desirable for technological or business reasons–for example, we may only want a single instance of a pool of database connections.
Structure
Key term | Description |
Static member | This contains the instance of the singleton class. |
Private constructor | This will prevent anybody else to instantiate the Singleton class. |
Static public method | This provides the global point of access to the Singleton object and returns the instance to the client calling class. |
UML Diagrams



Implementation Example
Lazy initialization
Let us look into a singleton implementation example in Java. The below code uses Lazy initialisation process.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
package com.technicaljungle.sample; public class SingletonExample { // Static member holds only one instance of the // SingletonExample class private static SingletonExample singletonInstance; // SingletonExample prevents any other class from instantiating private SingletonExample() { } // Providing Global point of access public static SingletonExample getSingletonInstance() { if (null == singletonInstance) { singletonInstance = new SingletonExample(); } return singletonInstance; } public void printSingleton(){ System.out.println("technicaljungle.com: Inside print Singleton"); } } Output: technicaljungle.com: instanceOne 1627800613 technicaljungle.com instanceOne 1627800613 instanceTwo 2065530879 |
When this class will be called from the client side using SingletonExample.getSingletonInstance().printSingleton(); then at the first time only an instance will be created. During second time onwards for all subsequent calls we will be referring to the same object and the getSingletonInstance() method returns the same instance of the SingletonExample class which was created during the first time. You can test this by adding a print statement the following code as:

Lazy initialisation is a method to implement the Singleton pattern to create an instance in the global access method.

Early loading
please note that double check locking might not work before Java 5. In such situation, we can use early loading mechanism.

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

Thread-Safe Singletons
The easier 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. The general implementation of this approach is like the following class:

The above code works absolutely fine in a single threaded environment and processes the result faster because of lazy initialization. However the above code might create some abrupt behaviour in the results in a multithreaded environment as in this situation multiple threads can possibly create multiple instance of the same SingletonExample class if they try to access the getSingletonInstance() method at the same time. Imagine a practical scenario where we have to create a log file and update it or while using a shared resource like Printer. To prevent this we must use some locking mechanism so that the second thread cannot use this getInstance()method until the first thread has completed the process.

Bill Pugh Singleton
A Bill Pugh Singleton is based on the “initialization on demand holder” idiom. This idiom uses inner classes and does not use any synchronization construct. It uses static blocks, but in a different way — and suggests using static inner classes.
We will rewrite the above Logger program using the Bill Pugh approach here.

enum singleton
Implementing Singleton in Java 5 or above version using Enum:
Enum is thread safe and implementation of Singleton through Enum ensures that your singleton will have only one instance even in a multithreaded environment. Let us see a simple implementation:

Reflection to Destroy Singleton Patterns
Reflection can be used to destroy all the above Singleton implementation approaches. Let’s see this with an example class:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
package com.technicaljungle.sample; import java.lang.reflect.Constructor; public class ReflectionSingletonTest { public static void main(String[] args) { EagerSingleton instanceOne = EagerSingleton.getInstance(); System.out.println("technicaljungle.com: instanceOne " + instanceOne.hashCode()); EagerSingleton instanceTwo = null; try { Constructor[] constructors = EagerSingleton.class.getDeclaredConstructors(); for (Constructor constructor : constructors) { //Below code will destroy the singleton pattern constructor.setAccessible(true); instanceTwo = (EagerSingleton) constructor.newInstance(); break; } } catch (Exception e) { System.out.println("instanceOne " + instanceOne.hashCode()); } System.out.println("technicaljungle.com instanceOne " + instanceOne.hashCode()); System.out.println("instanceTwo " + instanceTwo.hashCode()); } } class EagerSingleton { private static volatile EagerSingleton instance = new EagerSingleton(); // private constructor private EagerSingleton() { } public static EagerSingleton getInstance() { return instance; } } Output: technicaljungle.com: instanceOne 1627800613 technicaljungle.com instanceOne 1627800613 instanceTwo 2065530879 |
When you run the above test class, you will notice that the hashcode of both the instances is not same, which destroys the Singleton pattern. Reflection is very powerful and used in a lot of frameworks.
Overcome reflection issue: To overcome issue raised by reflection, enums are used because java ensures internally that enum value is instantiated only once.
Preserve single instance – clone
The below code is for preventing the singleton class to be cloned.Override the clone method and throw new CloneNotSupportedException()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
package com.technicaljungle.sample; public final class SingeltonCloneTest implements Cloneable { /** * @param args * @return */ private static SingeltonCloneTest instance = null; private SingeltonCloneTest() { System.out.println("Technical Jungle is implementing Cloneable interface"); } public static SingeltonCloneTest getInstance() { if (instance == null) { instance = new SingeltonCloneTest(); return instance; } return instance; } @Override protected Object clone() throws CloneNotSupportedException { /* * Here forcibly throws the exception for preventing to be cloned */ throw new CloneNotSupportedException(); // return super.clone(); } public static void main(String[] args) { SingeltonCloneTest test1 = SingeltonCloneTest.getInstance(); try { SingeltonCloneTest test2 = (SingeltonCloneTest) test1.clone(); } catch (CloneNotSupportedException e) { System.out.println("Technical Jungle is catching the CloneNotSupportedException"); e.printStackTrace(); } } } Output: Technical Jungle is implementing Cloneable interface Technical Jungle is catching the CloneNotSupportedException java.lang.CloneNotSupportedException at com.technicaljungle.sample.SingeltonCloneTest.clone(SingeltonCloneTest.java:30) at com.technicaljungle.sample.SingeltonCloneTest.main(SingeltonCloneTest.java:38) |
Serialisation vs De-serialisation
Sometimes in distributed systems, we need to implement a Serialyisable interface in our Singleton class so that we can store its state in a file system and retrieve it at a later point in time. Here is a small Singleton class that also implements a Serialisable interface.

The problem with the above serialised singleton class is that whenever we deserialise it, it will create a new instance of the class. Let’s see it with a simple program.

Uses of Singleton Design Pattern
Runtime.getRuntime()
Hardware printers
Cache: We can use the cache as a singleton object as it can have a global point of reference and for all future calls to the cache object the client application will use the in-memory object.
FAQs
Hey Users, Hope you like this article. I need your input for below questions.
Question 1 : Why can’t we use a static class instead of singleton?
Question 2: Can the singleton class be subclassed?
Question 3: Can there be multiple instance of singleton using cloning?
Question 4: What is the impact if we are creating another instance of singleton using serialisation and deserialisation?
Question 5: Which other pattern works with Singleton? Example please
Question 6: Which classes in JDK uses singleton pattern?
Pingback: design pattern | java | android - Technical Jungle