Online Pazarlama Bloğu

Singleton Design Pattern

September 13, 2018 • ☕️ 3 min read • 🏷

Translated by author into: English

Orjinali okuView all translated posts

Singleton is one of the simplest models of design patterns and is among creative design patterns. With Singleton, it is guaranteed that only one object of a class can be created in the system.

In some cases, only a single instance of a class is sufficient for us to perform our operations. For example, suppose we have a class that performs database connections. We may have more than one object to use this class. In such a case, it would be costly and unnecessary for each object to generate multiple database connection objects separately to use this class. To avoid this situation, a class in the system will produce a single object from the database class and a class that will allow objects that need the database class to access this object.

Using this design pattern, global variables in the system or variables with unchanged values ​​can be collected in a single object. The creation of a single object within the system can be accomplished with the help of routines and static variables.


Method 1. Classical Method

// Classical Java implementation of singleton design pattern 
class Singleton {
 
    private static Singleton instance; 
  
    // Private constructor to force use of getInstance() to create Singleton object 
    private Singleton() {} 
  
    public static Singleton getInstance() { 
        if (instance == null) 
            instance = new Singleton(); 
        return instance; 
    } 
}

In this method, the object is created the first time it is requested to be used. This object is used with the “instance == null” condition to prevent it from being reloaded whenever it wants to use it.

But this classic method is not thread safe. At the same time, two threads can create two different objects (or more threads). This is why we need to build a thread-safe structure.


Method 2. Synchronized getInstance()

// Thread Synchronized Java implementation of singleton design pattern
class Singleton { 

    private static Singleton instance; 
  
    private Singleton() {} 
  
    // Only one thread can execute this at a time 
    public static synchronized Singleton getInstance() { 
        if (instance == null) 
            instance = new Singleton(); 
        return instance; 
    } 
}

Here, using synchronized, we can only have one thread execute the getInstance () function at a time.

The disadvantage of this method is that it is expensive to use synchronized (control) each time the object is created and can degrade the performance of the program. However, if the performance of the getInstance () application is not critical to the application, this method provides a clean and simple solution.


Method 3. Eager Instantiation

// Static initializer based Java implementation of singleton design pattern
class Singleton { 

    private static Singleton instance = new Singleton(); 
  
    private Singleton() {} 
  
    public static Singleton getInstance() { 
        return instance; 
    }
}

Here, the object is created when the class is loaded into memory. This method should only be used if needed during the initialization of the program to the singleton class.


Method 4. Double Checked Locking

Notice that once an object is created, synchronization is no longer useful because the instance will no longer be null and any sequence of operations will produce consistent results.

So, when the instance is null, the lock on getInstance () is only valid once. This way we only get synchronization in the first step.

// Double Checked Locking based Java implementation of singleton design pattern
class Singleton { 

    private volatile static Singleton instance; 
  
    private Singleton() {} 
  
    public static Singleton getInstance() { 
        if (instance == null) { 
            // Thread safe
            synchronized (Singleton.class) { 
                // Check again as multiple threads can reach above step
                if (instance == null) 
                    instance = new Singleton(); 
            }
        }
        return instance; 
    } 
}

When Singleton instance is started, we have defined volatile that allows multiple threads to present the object variable correctly. With this method, we can greatly reduce the additional load that calls the synchronous method each time.

References

  1. https://en.wikipedia.org/wiki/Singleton_pattern
  2. https://www.geeksforgeeks.org/singleton-design-pattern/
  3. https://bidb.itu.edu.tr/eskiler/seyirdefteri/blog/2013/09/08/yegane-tasar%C4%B1m-kal%C4%B1b%C4%B1-(singleton-design-pattern)
  4. https://www.tutorialspoint.com/design_pattern/singleton_pattern.htm
  5. https://sourcemaking.com/design_patterns/singleton