Singleton Method Design Pattern

Last Updated : 5 May, 2026

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.

client_1
Singleton Design Pattern

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:

stack_memory
Components

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.

C++
// Static member to hold the single instance
private:
    static Singleton instance;
Java
// Static member to hold the single instance
private static Singleton instance;
Python
# Static member to hold the single instance
instance = None
JavaScript
// 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.

C++
// Private constructor to prevent external instantiation
class Singleton {
private:
    // Making the constructor as Private
    Singleton() {
        // Initialization code here
    }
};
Java
// Private constructor to prevent external instantiation
class Singleton {

    // Making the constructor as Private
    private Singleton()
    {
        // Initialization code here
    }
}
Python
"""
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
JavaScript
// 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.

C++
/* 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;
}
Java
// 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;
}
Python
"""
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()
JavaScript
"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.

race_condition_in_singleton_thread_unsafe_

Explanation

To understand the issue, consider two threads executing simultaneously:

  • Step 1: Thread 1 checks whether the instance (obj) is null. 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

C++
#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;
Java
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;
    }
}
Python
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
JavaScript
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

C++
#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;
Java
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;
    }
}
Python
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
JavaScript
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

C++
class Singleton {\nprivate:\n    static Singleton* obj;\n    Singleton() {}\npublic:\n    static Singleton* getInstance() { return obj; }\n};\n\nSingleton* Singleton::obj = new Singleton();
Java
class Singleton {
    private static Singleton obj = new Singleton();
    private Singleton() {}

    public static Singleton getInstance() { return obj; }
}
Python
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()
JavaScript
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

C++
#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;
Java
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;
    }
}
Python
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
JavaScript
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

C++
#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;
Java
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;
    }
}
Python
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()
JavaScript
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

C++
#include <iostream>

class Singleton {
public:
    static Singleton& getInstance() {
        static Singleton instance;
        return instance;
    }

    void doSomething() {
        std::cout << "Doing something..." << std::endl;
    }
private:
    Singleton() {}
};
Java
public enum Singleton {
    INSTANCE;

    public void doSomething() {
        System.out.println("Doing something...");
    }
}
Python
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...")
JavaScript
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.

C++
#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;
}
Java
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();
    }
}
Python
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()
JavaScript
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.
Comment

Explore