Singleton Design Pattern in Java
In the singleton pattern, a class that only has one instance and offers a universal point of access is taken into consideration.
It can also be defined in another way, a class must make sure that only one instance is produced and that only one object can be utilized by all other classes.
This particular design pattern falls under the category of a creational pattern because it provides one of the simplest ways to make an object.
Use of Singleton Pattern Design
This pattern design is mainly used to create the object such that only one object is created for a class and this class provides the technique of retrieving the class's unique object, removing the need to create it first.
This singleton pattern is also used in applications that involve datasets and multiple threads frequently
It is involved in the configuration files or specifications, threaded pools, caching, and logging, among many other things.
Implementation of Singleton Pattern Design
It implemented in three steps, such as:
- Make a Singleton Class first.
- Take the sole instance of the singleton class's object.
- Check the results.
There will be just one object class created. The static instance of the SingleObject class as well as the private function Object() [native code] are both available.
The SingleObject class offers a static method to return its static instance to the outside world.Our demo class, SingletonPatternDemo, will use the SingleObject class to obtain a SingleObject object.
Types of singleton pattern design
There are two types of singleton pattern design
- Early instantiation
- Using static block
- Lazy instantiation
- Thread Safe Singleton
- Lazy initialization with Double check locking
- Bill Pugh Singleton Implementation
Early instantiation
In short, it is defined as the process of instance creation when loading or at a load time.
This is considered to be the simplest method for developing a singleton time up ahead. An object of that class is created when the JVM loads the class into memory.It is accomplished by directly assigning an instance's reference.
When a computer will always use an instance of this class or when constructing an instance didn't accept up a lot of time or resources, it can be used.
Example
// Early Initialization
public class Early
{
private static final Early instance = new Early();
private Early()
{
//private constructor
}
public static EalrygetInstance()
{
return instance;
}
}
Using static block
This static block is the sub-part of the early instantiation or initialization.
The main difference is that objects are again created in static blocks so that we may access them immediately after they are created and handle exceptionsSimilarly, when a class is loaded, an object is produced.
// using static block
import java.io.*;
public class Sb
{
public static Sb instance;
private Sb()
{
// private constructor
}
static
{
instance = new Sb();
}
}
Advantages of Early instantiation
- extremely easy to use.
- certainly wastes resources. because whether or not it is necessary, a class instance is always produced.
- Instance creation that is not necessary wastes CPU time as well.
- There is no way to handle exceptions.
Lazy instantiation
In short, it is defined as the process of instance creation when needed
Going into it, here the object is created only when it is necessary.It is required to implement the method called asgetInstance(), which returns the instance. There is a null check that, if true, creates the object; else, it returns the one that has already been constructed.
The constructor is made final to ensure that the class cannot be created in any other way. Because objects are generated within methods, it is guaranteed that they won't be produced until and unless they are needed. To prevent direct access, instances are kept private.
The source wastage is prevented by this initialization method
Example
// With Lazy initialization
public class Li
{
private static GFG instance;
private Li()
{
// private constructor
}
public static Li getInstance()
{
if (instance == null)
{
// if instance is null, initialize
instance = new Li();
}
return instance;
}
}
Thread-safe singleton
Creating a thread-safe singleton allows for the preservation of singleton properties even in multithreaded environments. A singleton class is made thread-safe by synchronizing the getInstance() method so that multiple threads cannot access it simultaneously.
Example
public class Thread
{
private static Thread instance;
private Thread()
{
// private constructor
}
synchronized public static Thread getInstance()
{
if (instance == null)
{
instance = new Thread();
}
return instance;
}
}
Advantages of Lazy instantiation
- Only when it is necessary is an object created.
- It is also feasible for methods to handle exceptions.
- Each time, the null condition must be verified.
- No direct access is possible to instance.
Real-time Example for single pattern design in java
class Singleton
{
private int n = 20;
private Singleton()
{
}
private static class Helper {
private static final SingletonuniqueInstance = new Singleton();
}
public static Singleton getInstance() {
return Helper.uniqueInstance;
}
public int getNum() {
return n;
}
public void setNum(int n) {
this.n = n;
}
}
public class SingletonDemo {
public static void main(String args[]) {
Singleton singleInstance = Singleton.getInstance(); // first instance of the class
singleInstance.setNum(25);
Singleton secondInstance = Singleton.getInstance(); // second instance of the class
System.out.println(secondInstance.getNum()); // trying to get the class variable using getter method
}
}