Skip to main content

Command Palette

Search for a command to run...

Singleton design pattern

Updated
3 min readView as Markdown
N

Software Engineer II currently working at Akamai Technologies. Full Stack Web Development and DevOps enthusiast.

Singleton design pattern is one of the most commonly used design patterns. We use singleton design pattern when we need only one instance of a class. For example :

  • Logger : Suppose you are implementing a logging service in your application. All the components can write logs. Now, assume that each component has it’s own logger instance :

    • You will not have centralized logs.

    • You will have to handle logs of each component individually.

    • If something goes wrong in your application, it will be difficult for you to debug if you don’t have centralized logs because centralized logs help us to know the order of execution of code in our application.

  • Configuration manager : If your application needs a configuration manager for managing different configuration values then it must follow singleton design pattern.

  • Other examples : Parking station (i.e. there can be only one instance of parking station), chess-board (i.e. there can be only one instance of a chess board) etc.

Implementation of singleton design pattern

The below code snippet shows implementation of singleton design pattern in python programming language :

class Singleton:

    _instance = None

    def __new__(cls):
        if not cls._instance:
            cls._instance = super().__new__(cls)
        return cls._instance

    def __init__(self):
        # self is now pointing to the instance of the singleton class
        print(self)

if __name__ == "__main__":
    obj1 = Singleton()
    obj2 = Singleton()

Both obj1 and obj2 are denoting the same instance of Singleton class. Whenever you try to instantiate Singleton class, you will get the same instance.

Note : When you will execute the above code, the output will look like :

<__main__.Singleton object at 0x104bafc10>
<__main__.Singleton object at 0x104bafc10>

The output snippet shows that both obj1 and obj2 objects are referring to address 0x104bafc10, denoting single instance of Singleton class.

Thread safe Singleton class

The above implementation of Singleton class is not thread safe. If we create multiple threads then creation of single instance is not guaranteed.

Why it is not thread safe ?

If multiple threads are running, they can enter critical section simultaneously can can create their own instance.

Critical Section : The part/segment of the code where a shared resource is accessed. In our code, critical section is the part of the code where instance is created.

if not cls._instance:
   cls._instance = super().__new__(cls)
   return cls._instance

Thread safe implementation of Singleton class

import threading

class Singleton(threading.Thread):
    _instance = None
    _lock = threading.Lock()

    def __new__(cls):
        if not cls._instance:
            with cls._lock:
                if not cls._instance:
                    cls._instance = super().__new__(cls)
        return cls._instance

    def __init__(self):
        super().__init__()
        print(self)


if __name__ == "__main__":
    s1 = Singleton()
    s2 = Singleton()
    print(s1==s2)

Output :

<Singleton(Thread-1, initial)>
<Singleton(Thread-2, initial)>
True

Now, we are using Lock to ensure that only one thread can enter and execute the critical section of the code thereby creating only one instance of Singleton class.

💡
If you are not familiar with concurrent and parallel programming in python, you won’t be able to understand the thread safe implementation of Singleton class. If you want to learn “Concurrent and parallel programming in Python”, you can refer the course on linkedIn learning : https://www.linkedin.com/learning-login/share?account=2141129&forceAccount=false&redirect=https%3A%2F%2Fwww.linkedin.com%2Flearning%2Fcomplete-guide-to-parallel-and-concurrent-programming-in-python%3Ftrk%3Dshare_ent_url%26shareId%3DleXKc0YpSgObN7hrGZXSYQ%253D%253D