Singleton design pattern in Java
Singleton design pattern is a pattern in which a class must ensure that only a single instance should be created and a single object can be used by all other classes.
Singleton pattern restricts object CREATION of a class and ensures that only one instance of the class exists in the JVM.
The Singleton pattern is a creational design pattern that ensures that a class has only one instance, and provides a global point of access to that instance. In Java, the Singleton pattern is implemented by defining a private constructor, a private static variable of the same class type, and a public static method that returns the single instance of the class.
Table of Content :
- Introduction
- Create the instance variable at the time of class loading
- Use synchronized block inside the if loop and volatile variable
- Synchronize the getInstance() method.
- Thread Safe Singleton
- Lazy initialization with Double-check locking
- Singleton using Enum
- Bill Pugh Singleton Bill Pugh Singleton
- Summary
Create a singleton class in Java.
public class YourObject {
private static final Object lock = new Object();
private static volatile YourObject instance;
public static YourObject getInstance() {
YourObject r = instance;
if (r == null) {
synchronized(lock) { // While we were waiting for the lock, another
r = instance; // thread may have instantiated the object.
if (r == null) {
r = new YourObject();
instance = r;
}
}
}
return r;
}
}
}
1). Singleton with eager initialization
The object is created at the time of class loading, this is the easiest method to create a singleton class but it has a drawback that instance is created even though client application might not be using it.
Exception handling is not possible. May lead to resource wastage. Because the instance of the class is created always, whether it is required or not.
// Eager Initialization
public class EagerSingleton {
// public instance initialized when loading the class
private static final EagerSingleton instance = new EagerSingleton();
private EagerSingleton() {
// private constructor
}
public static EagerSingleton getInstance() {
return instance;
}
}
Advantages:
- Thread safety without synchronization
- Easy to implement
Disadvantages:
- Early creation of resources that might not be used in the application.
- The client application can’t pass any argument, so we can’t reuse it. For example, having a generic singleton class for database
- connection where client application supplies database server properties
2). Static block initialization
The object is created in a static block so that we can have access to its creation, like exception handling.
It's similar to eager initialization. except for object creation place.
Both eager initialization and static block initialization create the instance even before it’s being used and that is not a good way.
public class StaticBlockSingleton {
// public instance
public static StaticBlockSingleton instance;
private StaticBlockSingleton() {
// private constructor
}
static {
// static block to initialize instance
instance = new StaticBlockSingleton();
}
}
3). Lazy Initialization
In this way, it restricts the creation of the instance until it is requested for the first time.
the object is created only if it is needed.
An implementation of getInstance() method is required which returns the instance.
There is a null check that if the object is not created then create, otherwise return previously created.
the constructor is made final to ensure that the class cannot be instantiated in any other way.
public class LazySingleton {
/* private instance, so that it can be
accessed by only by getInstance() method */
private static LazySingleton instance;
private LazySingleton() {
// private constructor
}
//method to return instance of class
public static LazySingleton getInstance() {
if (instance == null) {
// if instance is null, initialize
instance = new LazySingleton();
}
return instance;
}
}
Problem with Lazy Singleton
Suppose there are two threads T1 and T2. They are trying to create the instance at the same time and check if "instance==null". Now both threads have identified instance variable as null thus they both assume they must create an instance. They both enter into the block and create the instances.we have two instances in our class, which breaks singleton pattern.
So we have a solution, to double-check if the instance is created or not and create the instance in a synchronized block. The example is given below.
4). Thread Safe Singleton
A Thread-Safe Singleton is a type of Singleton design pattern that ensures that a single instance of a class is created in a multithreaded environment. In other words, it ensures that the Singleton instance is accessed in a thread-safe way and avoids race conditions that may occur when multiple threads are accessing the same Singleton instance
public class ThreadSafeSingle {
private static volatile ThreadSafeSingle instance = null;
// private constructor
private ThreadSafeSingle() {}
public static ThreadSafeSingle getInstance() {
if (instance == null) {
synchronized(ThreadSafeSingle.class) {
// Double check
if (instance == null) {
instance = new ThreadSafeSingle();
}
}
}
return instance;
}
}
Advantages:
- Lazy initialization is possible.
- Thread safety is guaranteed
- The client application can pass arguments
Disadvantages:
getInstance() method is synchronized so it causes slow performance as multiple threads can’t access it simultaneously.
5). Lazy initialization with Double-check locking
In this solution, the getInstance is not synchronized but the block which creates instance is synchronized so that the minimum number of threads have to wait.
public class DoubleCheckLockSingleton {
private DoubleCheckLockSingleton() {
// private constructor
}
public static DoubleCheckLockSingleton getInstance() {
if (instance == null) {
//synchronized block removed
synchronized(DoubleCheckLockSingleton.class) {
if (instance == null) {
// if instance is null, initialize
instance = new DoubleCheckLockSingleton();
}
}
}
return instance;
}
}
Advantages:
- Lazy initialization is possible.
- It is also thread-safe.
- Performance overhead gets reduced because of the synchronized keyword.
6). Singleton using Enum
Enum provides implicit support for thread safety and only one instance is guaranteed.
Java enum singleton is also a good way to have a Singleton design pattern in Java.
public enum EnumSingleton {
INSTANCE("property want to initialize at once");
// @Getter and @Setter
private String info;
private EnumSingleton(String info) {
this.info = info;
}
public EnumSingleton getInstance() {
return INSTANCE;
}
}
7). Bill Pugh Singleton
Create the Singleton class using an inner static helper class.
public class Singleton {
private Singleton() {}
private static class SingletonHelper {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonHelper.INSTANCE;
}
}
Here we need an instance, the SingletonHelper class will not be initialized until required and you can still use other static members of Singleton class. This is one of the best solutions.
How to achieve thread-safety in Singleton Class?
There are the following ways through which we can achieve thread-safety.
TestExample
public class YourObject {
private static final Object lock = new Object();
private static volatile YourObject instance;
public static YourObject getInstance() {
YourObject r = instance;
if (r == null) {
synchronized(lock) { // While we were waiting for the lock, another
r = instance; // thread may have instantiated the object.
if (r == null) {
r = new YourObject();
instance = r;
}
}
}
return r;
}
}
}
We covered the following questions in this article
Use of singleton class in java
Singleton classes in Java are commonly used when you need to ensure that there is only one instance of a class created and that it can be accessed from anywhere in the application. Here are some common scenarios where a singleton class might be used:
- Database Connection : A singleton class can be used to manage a database connection so that there is only one connection to the database throughout the application.
- Configuration Settings : A singleton class can be used to store and manage application configuration settings, such as properties or environment variables, to ensure that they are consistent throughout the application.
- Logging : A singleton class can be used to manage logging throughout the application, so that log messages are written to a single file or database table.
- Caching : A singleton class can be used to manage a cache of frequently accessed data, so that it is readily available to the application without having to repeatedly fetch it from the database or other external sources.
- GUI Components : A singleton class can be used to manage GUI components, such as dialog boxes or menu bars, so that they are consistent throughout the application.
- The singleton class must provide an access point to get the instance/object of the class.
- Singleton pattern is used for logging, driver objects, caching, and thread pool.
- Benefits of Singleton design pattern
- Saves memory because the object is not created at each request. An only single instance is reused again and again
- Singleton design pattern is also used in other design patterns like Abstract Factory, Builder, Prototype, Facade, etc.
- Singleton design pattern is used in core java classes also, for example, java.lang.Runtime, java.awt.Desktop.
- Singleton pattern is mostly used in multi-threaded and database applications. It is used in logging, caching, thread pools, configuration settings, etc.
Overall, the Singleton pattern is useful in situations where there should be only one instance of a class, and where that instance needs to be easily accessible from anywhere in the application.
When to use singleton design pattern in java
Benefits of Singleton Pattern
Singleton class in java example with synchronized
How to get the current date in java 8?
What is a singleton design pattern in java?
How to break a singleton pattern in java?
How to reset the singleton object in java?
Can singleton class be inherited in java?
How to create a singleton class using enum in java?
In this article, we have seen the Singleton Class design pattern in Java using different ways. All source code in the article can be found in the GitHub repository.
0 Comments
Post a Comment