Simple Singleton Pattern in Java
In software engineering, the singleton pattern
is a design pattern that restricts the instantiation of a class to one object
. This is useful when exactly one object is needed to coordinate actions across the system. The concept is sometimes generalized to systems that operate more efficiently when only one object exists, or that restrict the instantiation to a certain number of objects.
Example:
Window managers, print spoolers, and filesystems are prototypical examples. Typically, those types of objects — known as singletons — are accessed by disparate objects throughout a software system, and therefore require a global point of access.
The Singleton design pattern addresses all of the above concerns.
With the Singleton design pattern you can:
- Ensure that only one instance of a class is created
- Provide a global point of access to the object
- Allow multiple instances in the future without affecting a singleton class’s clients
Another must read:
- Java: Union of Two Arrays using Java Collection Class
- How to iterate through Java List? 4 way to iterate through loop?
Here is a singleton design pattern example.
Simple Singleton Pattern: (Lazy Initialization + ThreadSafe with synchronized block)
This implementation uses the same double-checked locking mechanism as in the previous implementation. The added logging statements help demonstrate when the instance is being created and returned.
package com.crunchify.tutorials; public class CrunchifySingleton { private static CrunchifySingleton instance; private CrunchifySingleton() { System.out.println("CrunchifySingleton instance created"); } // Lazy Initialization (If required then only) public static CrunchifySingleton getInstance() { if (instance == null) { // Thread Safe. Might be costly operation in some case synchronized (CrunchifySingleton.class) { if (instance == null) { instance = new CrunchifySingleton(); } } } System.out.println("Returning CrunchifySingleton instance"); return instance; } }
It is clear from the example that the traditional approach is not thread-safe, as it’s possible that before a thread creates the Singleton instance, another thread proceeds to the instantiation part of the code (i.e. instance = new Object();
), because the condition instance == null
is still true.
Thread-Safe Singleton Pattern in Java:
Here is the updated code that implements a thread-safe Singleton pattern in Java:
In this implementation, the instance
variable is declared as volatile
to ensure that multiple threads handle the variable correctly when creating the instance. The double-checked locking mechanism is still used to ensure that only one instance of the CrunchifySingleton
class is created, even in a multithreaded environment.
public class CrunchifySingleton { private static volatile CrunchifySingleton instance; private CrunchifySingleton() { System.out.println("CrunchifySingleton instance created"); } public static CrunchifySingleton getInstance() { if (instance == null) { synchronized (CrunchifySingleton.class) { if (instance == null) { instance = new CrunchifySingleton(); } } } System.out.println("Returning CrunchifySingleton instance"); return instance; } }
Through this approach we provide the necessary thread-safety, as the Singleton instance is created at class-load time.
Any subsequent calls to the getInstance() method will return the already created instance.
Let me know if you have any question understanding this.