The Singleton Design Pattern ensures that a class has only one instance and provides a global access point to it. It is used when we want centralized control of resources, such as managing database connections, configuration settings or logging.
- Prevents accidental creation of multiple instances and ensures controlled, efficient use of resources like memory and connections.
- Simplifies coordination across different parts of the application by providing a single shared instance.
Example: A Database Connection Manager uses a single shared instance instead of creating multiple connections. This ensures efficient resource usage and consistent access to the database across the application.

In the above Diagram:
- All clients (Client-1, Client-2, Client-3) send requests but receive the same single instance (Instance-1), showing that only one object is created.
- The Singleton object acts as a central access point, ensuring every request is handled by the same shared instance.
- This avoids multiple object creation, leading to efficient resource usage and consistent behavior (e.g., one database connection manager).
Real-World Applications
The Singleton Pattern ensures a single, globally accessible instance of a class, providing controlled access and consistent behavior across an application.
- Logging Systems : Maintain a consistent logging mechanism across an application.
- Configuration Managers : Centralize access to configuration settings.
- Database Connections : Manage a single point of database access.
- Thread Pools : Efficiently manage a pool of threads for concurrent tasks.
Features
The Singleton Pattern ensures that a class has only one instance and provides a global point of access to it, while efficiently managing resources.
- Single Instance: Ensures only one object of the class exists in the JVM.
- Global Access Point: Provides a centralized way to access the instance.
- Lazy or Eager Initialization: An Instance can be created at class load time (eager) or when first needed (lazy).
- Thread Safety: Can be designed to work correctly in multithreaded environments.
- Resource Management: Useful for managing shared resources like configurations, logging or database connections.
Components
The main key components of Singleton Method Design Pattern are:

1. Static Member
The Singleton pattern employs a static member within the class. This static member ensures that memory is allocated only once, preserving the single instance of the Singleton class.
// Static member to hold the single instance
private:
static Singleton instance;
// Static member to hold the single instance
private static Singleton instance;
# Static member to hold the single instance
instance = None
// Static member to hold the single instance
let instance = null;
2. Private Constructor
The Singleton pattern incorporates a private constructor, which serves as a barricade against external attempts to create instances of the Singleton class. This ensures that the class has control over its instantiation process.
// Private constructor to prevent external instantiation
class Singleton {
private:
// Making the constructor as Private
Singleton() {
// Initialization code here
}
};
// Private constructor to prevent external instantiation
class Singleton {
// Making the constructor as Private
private Singleton()
{
// Initialization code here
}
}
"""
Private constructor to prevent external instantiation
"""
class Singleton:
def __new__(cls):
if not hasattr(cls, 'instance'):
cls.instance = super(Singleton, cls).__new__(cls)
# Initialization code here
return cls.instance
@classmethod
def get_instance(cls):
if not hasattr(cls, 'instance'):
cls()
return cls.instance
# Private constructor
def __init__(self):
if hasattr(self.__class__, 'instance'):
raise TypeError('Cannot create a new instance of Singleton')
# Initialization code here
// Private constructor to prevent external instantiation
class Singleton {
// Making the constructor as Private
constructor() {
if (Singleton.instance) {
throw new Error('Use Singleton.getInstance() to get the singleton instance.');
}
Singleton.instance = this;
// Initialization code here
}
static getInstance() {
if (!Singleton.instance) {
Singleton.instance = new Singleton();
}
return Singleton.instance;
}
}
3. Static Factory Method
A crucial aspect of the Singleton pattern is the presence of a static factory method. This method acts as a gateway, providing a global point of access to the Singleton object. When someone requests an instance, this method either creates a new instance (if none exists) or returns the existing instance to the caller.
/* Static factory method for global access */
#include <iostream>
using namespace std;
class Singleton {
private:
static Singleton* instance;
Singleton() {} // Private constructor
public:
static Singleton* getInstance() {
if (instance == nullptr) {
instance = new Singleton();
}
return instance;
}
void display() {
cout << "Singleton instance." << endl;
}
};
// Initialize the static member
Singleton* Singleton::instance = nullptr;
int main() {
Singleton* s = Singleton::getInstance();
s->display();
return 0;
}
// Static factory method for global access
public static Singleton getInstance()
{
// Check if an instance exists
if (instance == null) {
// If no instance exists, create one
instance = new Singleton();
}
// Return the existing instance
return instance;
}
"""
Static factory method for global access
"""
class Singleton:
_instance = None
def __new__(cls):
if cls._instance is None:
cls._instance = super(Singleton, cls).__new__(cls)
return cls._instance
@staticmethod
def get_instance():
return Singleton()
def display(self):
print("Singleton instance.")
s = Singleton.get_instance()
s.display()
"use strict";
/* Static factory method for global access */
class Singleton {
static instance = null;
constructor() {
if (Singleton.instance) {
return Singleton.instance;
}
Singleton.instance = this;
}
static getInstance() {
if (!Singleton.instance) {
Singleton.instance = new Singleton();
}
return Singleton.instance;
}
display() {
console.log('Singleton instance.');
}
}
const s = Singleton.getInstance();
s.display();
Thread-Safety in Singleton Design Pattern
In a multi-threaded environment, the basic implementation of the Singleton Design Pattern may fail due to a problem known as a race condition. When multiple threads try to access the Singleton instance at the same time, it can lead to the creation of more than one instance, which violates the core principle of Singleton.

Explanation
To understand the issue, consider two threads executing simultaneously:
- Step 1: Thread 1 checks whether the instance (
obj) isnull. Since no object has been created yet, the condition is true. - Step 2: Before Thread 1 creates the object, it gets paused (context switching happens).
- Step 3: Thread 2 now runs and also checks
obj == null. It also finds it true. - Step 4: Thread 2 creates a new Singleton object.
- Step 5: Thread 1 resumes execution and, unaware that an object has already been created, also creates another instance.
Different Ways of Implementation
Sometimes we need to have only one instance of our class for example a single DB connection shared by multiple objects as creating a separate DB connection for every object may be costly. Similarly, there can be a single configuration manager or error manager in an application that handles all problems instead of creating multiple managers.
1. Classic (Lazy Initialization)
In this method, the Singleton instance is created only when it is first requested. This helps save memory and resources, but the basic implementation is not thread-safe.
Example: Classical Java implementation of singleton design pattern
#include <iostream>
class Singleton {
private:
static Singleton* obj;
Singleton() {}
public:
static Singleton* getInstance() {
if (obj == nullptr)
obj = new Singleton();
return obj;
}
};
Singleton* Singleton::obj = nullptr;
class Singleton {
private static Singleton obj;
// private constructor to force use of getInstance() to create Singleton object
private Singleton() {}
public static Singleton getInstance()
{
if (obj == null)
obj = new Singleton();
return obj;
}
}
class Singleton:
_instance = None
def __new__(cls):
if cls._instance is None:
cls._instance = super(Singleton, cls).__new__(cls)
return cls._instance
# Private constructor equivalent
def __init__(self):
if not hasattr(self, 'initialized'):
self.initialized = True
class Singleton {
static instance = null;
// Private constructor equivalent
constructor() {
if (Singleton.instance) {
throw new Error('Use Singleton.getInstance() to get the instance.');
}
Singleton.instance = this;
}
static getInstance() {
if (!Singleton.instance) {
Singleton.instance = new Singleton();
}
return Singleton.instance;
}
}
- getInstance() is declared static, so it can be called without creating an object of the class.
- The first call to getInstance() creates the singleton object.
- Subsequent calls return the same instance, ensuring only one object exists.
Note: Singleton obj is not created until we need it and call the getInstance() method. This is called lazy instantiation. The main problem with the above method is that it is not thread-safe. Consider the following execution sequence.
This execution sequence creates two objects for the singleton. Therefore this classic implementation is not thread-safe.
2. Thread-Safe (Synchronized)
Make getInstance() synchronized to implement Singleton Method Design Pattern
Example: Thread Synchronized Java implementation of singleton design pattern
#include <iostream>
class Singleton {
private:
static Singleton* obj;
Singleton() {}
public:
// Only one thread can execute this at a time
static Singleton* getInstance() {
if (obj == nullptr) {
obj = new Singleton();
}
return obj;
}
};
Singleton* Singleton::obj = nullptr;
class Singleton {
private static Singleton obj;
private Singleton() {}
// Only one thread can execute this at a time
public static synchronized Singleton getInstance()
{
if (obj == null)
obj = new Singleton();
return obj;
}
}
class Singleton:
_instance = None
def __new__(cls):
if cls._instance is None:
cls._instance = super(Singleton, cls).__new__(cls)
return cls._instance
# Only one thread can execute this at a time
@staticmethod
def get_instance():
if Singleton._instance is None:
Singleton._instance = Singleton()
return Singleton._instance
class Singleton {
static obj = null;
constructor() {
if (Singleton.obj) {
throw new Error('Use Singleton.getInstance() to get the instance.');
}
}
// Only one thread can execute this at a time
static getInstance() {
if (Singleton.obj === null) {
Singleton.obj = new Singleton();
}
return Singleton.obj;
}
}
- Using synchronized ensures that only one thread at a time can execute getInstance().
- This approach is safe for multithreading but can reduce performance due to the overhead of synchronization.
- If performance is not critical, this method is a simple and reliable way to implement a singleton.
3. Eager Initialization (Static Block)
In this method, the Singleton instance is created at the time of class loading, regardless of whether it is used or not. It is simple and thread-safe, but may lead to unnecessary resource usage.
Example: Static initializer based Java implementation of singleton design pattern
class Singleton {\nprivate:\n static Singleton* obj;\n Singleton() {}\npublic:\n static Singleton* getInstance() { return obj; }\n};\n\nSingleton* Singleton::obj = new Singleton();
class Singleton {
private static Singleton obj = new Singleton();
private Singleton() {}
public static Singleton getInstance() { return obj; }
}
class Singleton:\n _instance = None\n def __new__(cls):\n if cls._instance is None:\n cls._instance = super(Singleton, cls).__new__(cls)\n return cls._instance\n\n @staticmethod\n def get_instance():\n return Singleton()
class Singleton {\n static obj = new Singleton();\n private constructor() {}\n static getInstance() { return Singleton.obj; }\n}
- The singleton instance is created in a static initializer, which runs when the class is loaded.
- This approach is thread-safe because JVM handles static initialization.
- Best used when the singleton class is lightweight and needed throughout the program execution.
4. Double-Checked Locking (Most Efficient)
Use “Double Checked Locking” to implement singleton design pattern
Example: Double Checked Locking based Java implementation of singleton design pattern
#include <mutex>
class Singleton {
private:
static Singleton* obj;
std::mutex mtx;
Singleton() {}
public:
static Singleton* getInstance() {
if (obj == nullptr) {
std::lock_guard<std::mutex> lock(mtx);
if (obj == nullptr)
obj = new Singleton();
}
return obj;
}
};
Singleton* Singleton::obj = nullptr;
class Singleton {
private static volatile Singleton obj = null;
private Singleton() {}
public static Singleton getInstance()
{
if (obj == null) {
// To make thread safe
synchronized (Singleton.class)
{
// check again as multiple threads can reach above step
if (obj == null)
obj = new Singleton();
}
}
return obj;
}
}
import threading
class Singleton:
_instance = None
_lock = threading.Lock()
def __new__(cls):
if not cls._instance:
with cls._lock:
if not cls._instance:
cls._instance = super(Singleton, cls).__new__(cls)
return cls._instance
class Singleton {
static instance = null;
constructor() {
if (Singleton.instance) {
throw new Error('Use Singleton.getInstance() instead of new.');
}
}
static getInstance() {
if (!Singleton.instance) {
Singleton.instance = new Singleton();
}
return Singleton.instance;
}
}
- The obj is declared volatile to ensure correct handling by multiple threads during initialization.
- This approach reduces the overhead of synchronizing every time getInstance() is called.
- It provides a thread-safe and efficient way to create the singleton instance.
5. Static Inner Class (Best Java-Specific Way)
In Java, a Singleton can be implemented using a static inner class.
- A class is loaded into memory only once by the JVM.
- An inner class is loaded only when it is referenced.
- Therefore, the Singleton instance is created lazily, only when the getInstance() method accesses the inner class.
Example: using class loading concept singleton design pattern
#include <iostream>
class Singleton {
private:
Singleton() {
std::cout << "Instance created" << std::endl;
}
static Singleton* instance;
public:
static Singleton* getInstance() {
static Singleton instance;
return &instance;
}
};
Singleton* Singleton::instance = nullptr;
public class Singleton {
private Singleton() {
System.out.println("Instance created");
}
private static class SingletonInner{
private static final Singleton INSTANCE=new Singleton();
}
public static Singleton getInstance()
{
return SingletonInner.INSTANCE;
}
}
class Singleton:
_instance = None
def __new__(cls):
if not cls._instance:
cls._instance = super(Singleton, cls).__new__(cls)
print("Instance created")
return cls._instance
def __init__(self):
pass
@staticmethod
def get_instance():
return Singleton()
class Singleton {
constructor() {
if (!Singleton.instance) {
console.log('Instance created');
Singleton.instance = this;
}
return Singleton.instance;
}
static getInstance() {
if (!Singleton.instance) {
Singleton.instance = new Singleton();
}
return Singleton.instance;
}
}
- A private static inner class (SingletonInner) holds the singleton instance.
- The instance is accessed via the getInstance() method of the outer class.
- Being static, the inner class is loaded only once when INSTANCE is first accessed, ensuring lazy initialization and thread-safety.
6. Enum Singleton
In Java, a Singleton can also be implemented using an enum, which is the simplest and safest approach. Enums are loaded by the JVM only once, and each enum constant is created exactly one time. Therefore, the Singleton instance is created safely when the enum is first accessed.
Example: Enum-based Singleton
#include <iostream>
class Singleton {
public:
static Singleton& getInstance() {
static Singleton instance;
return instance;
}
void doSomething() {
std::cout << "Doing something..." << std::endl;
}
private:
Singleton() {}
};
public enum Singleton {
INSTANCE;
public void doSomething() {
System.out.println("Doing something...");
}
}
class Singleton:
_instance = None
def __new__(cls):
if cls._instance is None:
cls._instance = super(Singleton, cls).__new__(cls)
return cls._instance
def doSomething(self):
print("Doing something...")
class Singleton {
constructor() {
if (!Singleton.instance) {
Singleton.instance = this;
}
return Singleton.instance;
}
doSomething() {
console.log("Doing something...");
}
}
Singleton.instance = null;
- INSTANCE is the single allowed object of the enum.
- The JVM ensures that the enum is thread-safe, created only once, and cannot be instantiated again.
- It also automatically protects against serialization and reflection issues.
- When Singleton.INSTANCE is accessed for the first time, the enum is loaded and the instance is initialized only once.
Implementation
Example: The implementation of the singleton Design pattern is very simple and consists of a single class.
#include <iostream>
class Singleton {
private:
static Singleton* instance;
Singleton() {
std::cout << "Singleton is Instantiated." << std::endl;
}
public:
static Singleton* getInstance() {
if (instance == nullptr)
instance = new Singleton();
return instance;
}
static void doSomething() {
std::cout << "Something is Done." << std::endl;
}
};
Singleton* Singleton::instance = nullptr;
int main() {
Singleton::getInstance()->doSomething();
return 0;
}
import java.io.*;
class Singleton {
// static class
private static Singleton instance;
private Singleton()
{
System.out.println("Singleton is Instantiated.");
}
public static Singleton getInstance()
{
if (instance == null)
instance = new Singleton();
return instance;
}
public static void doSomething()
{
System.out.println("Something is Done.");
}
}
class GFG {
public static void main(String[] args)
{
Singleton.getInstance().doSomething();
}
}
class Singleton:
_instance = None
def __new__(cls):
if cls._instance is None:
print('Singleton is Instantiated.')
cls._instance = super(Singleton, cls).__new__(cls)
return cls._instance
@staticmethod
def do_something():
print('Something is Done.')
if __name__ == '__main__':
Singleton.do_something()
class Singleton {
static instance = null;
constructor() {
if (Singleton.instance) {
return Singleton.instance;
}
console.log('Singleton is Instantiated.');
Singleton.instance = this;
}
static getInstance() {
if (!Singleton.instance) {
Singleton.instance = new Singleton();
}
return Singleton.instance;
}
static doSomething() {
console.log('Something is Done.');
}
}
Singleton.getInstance().doSomething();
Output
Singleton is Instantiated. Something is Done.
Advantages
The Singleton pattern offers several benefits when controlled access to a single instance is required:
- Ensures only one instance exists, preventing inconsistent states.
- Saves memory and system resources by avoiding multiple object creation.
- Provides a global access point, making it easy to share the same instance across the application.
Disadvantages
Despite its benefits, Singleton can introduce certain design challenges:
- Can create tight coupling since many classes depend on a global instance.
- Difficult to unit test due to shared global state.
- May cause issues in multithreaded environments if not implemented carefully.