Singleton class in java follows the principle that the class must make sure that only one instance is produced and that only one object may be utilized by all other classes. We use this when we coordinate the actions using only one object across the system. Singleton classes are used for logging, driver objects, caching and thread pool, and database connections. The singleton pattern is implemented by creating a private constructor, a private static instance variable, and a public static method (getInstance) that returns the instance of the class. The getinstance method is used to get the single instance of the class, ensuring that only one instance of the class exists in the JVM.
Java Singleton Class
A Singleton class in Java is a class that allows only one instance of itself to be created and ensures that there is only one instance of the class throughout the execution of the program. It is a creational design pattern that restricts the instantiation of a class to a single instance.
A singleton class in Java can be created in several ways. One of the simplest ways is to make the constructor of the class private so that no other class can access it. The instance of the class can then be created inside the class itself using the private constructor.
public class Singleton {
private static Singleton instance = null;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
In the above example, the getInstance() method is used to get the instance of the class. The first time the method is called, it creates an instance of the class and returns it. The subsequent times, it returns the same instance without creating a new one.
Another way to create a singleton class in java is to make the instance of the class final and create it in a static block. The static block ensures that the instance is created only once when the class is loaded.
public class Singleton {
private static final Singleton instance = new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return instance;
}
}
It is important to note that singleton classes should be thread-safe. When multiple threads access the singleton class in java at the same time, it can lead to race conditions and unexpected behavior. To ensure that the singleton class in java is thread-safe, the getInstance() method can be made synchronized.
public class Singleton {
private static Singleton instance = null;
private Singleton() {}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
Summarising, a singleton class in Java is a class that ensures that only one instance of the class is created throughout the execution of the program. It is a useful design pattern for situations where a class should have only one instance, such as a database connection, a logging class, or a configuration class. By making the constructor private and using a static method to access the instance, the singleton pattern can be implemented in Java.
Difference between Normal and Singleton Class in Java
A normal Java class can have multiple instances, meaning that each time you create an object of that class, you get a new and separate object. In contrast, a singleton class in java is a class that allows only one instance of itself to be created, and that instance is usually shared by all parts of the application that need to use it.
Here are some key differences between a normal class and a singleton class:
- Instance creation: In a normal class, you can create as many instances as you want, but in a singleton class, you can only create one instance.
- Object reference: In a normal class, each object has its own reference, but in a singleton class, all parts of the application share the same reference to the one and only instance.
- Global access: A singleton class is often used to provide a global point of access to its methods and properties. This means that any part of the application can access the singleton instance and use its methods, while in a normal class, you have to create an instance of the class and then use its methods.
- Design pattern: The singleton pattern is a design pattern that restricts a class to have only one instance while promoting global access to this instance.
- Constructor: In a normal class, the constructor is used to create an instance of the class. In a singleton class, the constructor is often made private to prevent other classes from creating an instance of the singleton class.
Example of Singleton Class in Java
Here we will look at the example of a singleton class in java with proper explanation and code:
class Singleton { private static Singleton single_instance = null; public String s; private Singleton() { s = "Hello I am a string part of Singleton class"; } public static Singleton getInstance() { if (single_instance == null) single_instance = new Singleton(); return single_instance; } } class PrepBytes { public static void main(String args[]) { Singleton x = Singleton.getInstance(); Singleton y = Singleton.getInstance(); Singleton z = Singleton.getInstance(); System.out.println("Hashcode of x is " + x.hashCode()); System.out.println("Hashcode of y is " + y.hashCode()); System.out.println("Hashcode of z is " + z.hashCode()); // Condition check if (x == y && y == z) { System.out.println( "Three objects point to the same memory location on the heap i.e, to the same object"); } else { // Print statement System.out.println( "Three objects DO NOT point to the same memory location on the heap"); } } }
Output
Hashcode of x is 1555009629
Hashcode of y is 1555009629
Hashcode of z is 1555009629
Three objects point to the same memory location on the heap i.e, to the same object
Explanation of the above code
When we execute the getInstance() function for the first time in a singleton class, it generates a class object with the name single instance and returns it to the variable. A single instance is converted from null to an object since it is static. Since a single instance is not null, the next time we try to call the getInstance() function, it is returned to the variable rather than creating a new instance of the Singleton class. The if condition handles this portion.
By using the static method getInstance in the main class, we instantiate the singleton class in java with the three objects x, y, and z. (). However, as indicated in the picture, variables y and z are really set to point to object x once object x is created. Therefore, when we access the variables of objects y and z, whatever changes we make to object x’s variables are reflected. Additionally, when we access the variables of objects x and y, changes made to the object z’s variables are reflected.
Methods to Create Singleton Design Pattern in Java
There are several methods to create a singleton design pattern in different programming languages. Here are some common methods:
- Using a private constructor: In this method, the class constructor is made private so that it can only be accessed within the class. A static method is used to return the single instance of the class. If an instance has not been created yet, the method creates it and returns it. If an instance has already been created, the method returns the existing instance.
- Using a static instance variable: This method uses a static instance variable to hold the single instance of the class. A static method is used to return the single instance of the class. If an instance has not been created yet, the method creates it and returns it. If an instance has already been created, the method returns the existing instance.
- Using the Double Checked Locking pattern: This method uses a lock mechanism to ensure that only one instance of the class is created. A static instance variable is used to hold the single instance of the class. The method first checks if the instance has been created and returns it if it has. If the instance has not been created, the method acquires a lock, checks again if the instance has been created, and creates it if it has not. The lock is then released.
- Using the Singleton Monostate pattern: In this method, the state of the class is kept in a separate class, and the singleton class in java acts as an accessor for the state. Multiple instances of the singleton class in java can be created, but all of them share the same state.
- Using the Singleton using the Borg pattern: This method uses the same idea as the Monostate pattern, but with a little variation. In this method, the state of the class is kept in a class variable, and all instances of the singleton class share this state. The difference between this and the Monostate pattern is that the state is stored in a class variable instead of a separate class.
Forms of Singleton Design Pattern
There are several ways to implement the Singleton design pattern in Java. Here are some common methods:
- Early Instantiation: In this method, the singleton instance is created at the time of class loading, and it is stored as a private static field.
- Lazy Initialization: In this method, the singleton instance is created only when it is first accessed. This is done by checking if the instance has already been created, and if not, creating it and storing it in a private static field.
Each of these methods has its own advantages and disadvantages, and the best method to use depends on the specific requirements of the project.
Lazy Instantiation in Singleton Pattern in Java
The Lazy Initialization method of the Singleton pattern in Java involves creating the singleton instance only when it is first accessed. Here’s an example implementation:
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
In this implementation, the instance variable is a private static field that holds the singleton instance. The constructor of the class is also private to prevent direct instantiation of the class. The getInstance method is a public static method that returns the singleton instance. If the instance variable is null, it means that the instance has not yet been created, so the method creates it and stores it in the instance variable. If the instance variable is not null, it means that the instance has already been created, so the method simply returns the existing instance.
This method is simple and straightforward, but it is not thread-safe. In a multi-threaded environment, it is possible for two or more threads to simultaneously access the getInstance method and create separate instances of the Singleton class, which would break the singleton pattern. To make this method thread-safe, the Double-checked Locking method can be used instead.
Early Instantiation in Singleton Pattern in Java
The Singleton pattern is a design pattern that ensures that a class has only one instance while providing a global point of access to this instance. Here is an example of an early implementation of a Singleton pattern in Java:
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
This implementation has a race condition, which can cause multiple instances to be created if multiple threads attempt to access getInstance() at the same time. To avoid this issue, the getInstance() method needs to be made thread-safe. A common way to achieve this is to use a synchronized block, as shown below:
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
Significance of Serialization in Singleton Pattern in Java
Serialization is a process in Java that allows objects to be written to a stream or a file and then reconstructed back into objects. The significance of serialization in the singleton pattern lies in the fact that if a singleton class in java is serializable, its instance can be written to a stream, and upon reconstruction, a new instance of the singleton class in java can be created, which violates the basic principle of the singleton pattern – to have only one instance of the class in the entire JVM.
To prevent this from happening, it’s recommended to implement the readResolve method in the singleton class. The readResolve method is called by the ObjectInputStream after it has deserialized an object and before it returns it to the caller. By returning the already existing singleton instance in this method, we ensure that only one instance of the singleton class in java exists in the JVM, even after serialization and deserialization.
Significance of Classloader in Singleton Pattern in Java
The class loader is a fundamental component of the Java runtime environment, responsible for loading class files into the JVM and making them accessible to the application. In the context of the singleton pattern, the class loader plays a crucial role in ensuring that a singleton class in java has only one instance across the entire JVM.
If multiple class loaders are used in an application, each class loader would have its own instance of a singleton class. This would defeat the purpose of the singleton pattern as each class loader would have a separate instance of the singleton class. To prevent this, it’s recommended to ensure that the singleton class in java is loaded by a single-class loader.
One way to do this is to make sure that the singleton class in java is only loaded by the system class loader, which is responsible for loading the core Java libraries and classes. Another approach is to use the enum singleton pattern, which ensures a single instance across the entire JVM and eliminates the need to worry about class loaders.
Advantages of Singleton Class in Java
Here we will discuss the advantages of using a singleton class in java.
- Single Point of Control: The singleton pattern ensures that there is only one instance of the class in the JVM, providing a single point of control for the entire application.
- Improved Performance: By having a single instance of the class, memory utilization is optimized, and performance is improved compared to having multiple instances of the same class.
- Global Access: A singleton class in java provides a global point of access, making it easy to access the same instance of the class from anywhere in the application.
- Flexibility: The singleton pattern allows the number of instances of the class to be changed easily in the future if required.
Disadvantages of Singleton Class in Java
We will discuss the disadvantages of using singleton class in java.
- Testing Difficulty: Testing a singleton class in java can be difficult as it tightly couples the class with the rest of the application, making it challenging to isolate and test.
- Tight Coupling: The singleton class in java can become tightly coupled with the rest of the application, making it challenging to modify or extend the class in the future.
- Global State: The singleton class in java maintains a global state, which can lead to unexpected behavior if not managed properly.
- Lacks Flexibility: The singleton pattern limits the flexibility of the class, as it can only have one instance, making it challenging to implement in certain scenarios where multiple instances are required.
Conclusion
In the above article we have discussed singleton class in java followed by the difference between a normal class and a singleton class in java we have clearly explained the concept behind singleton class in java with the help of examples and its explanation, Along with this we have also discussed the methods of singleton pattern, and forms of singleton design pattern followed by some significances and advantages and disadvantages of singleton classes in java.
Frequently Asked Questions
1. Mention some of the advantages of the lazy initialization method in singleton class in Java.
We can perform exception handling in this technique, The object is only created when necessary.
2. What is the Lazy Load Method in singleton class in Java?
The JVM will only load static data members when necessary when using the lazy load technique. Therefore, no object is created when the singleton class is loaded into the JVM.
3. What is the need for a singleton class in Java?
A singleton class is used in Java to ensure that there is only one instance of the class in the entire JVM. This provides a single point of control for the entire application, improves performance by reducing memory utilization, and provides a global point of access to the instance of the class.
4. Can we extend a singleton class in Java?
Yes, a singleton class in Java can be extended. However, the child class may not behave as a singleton class unless it is designed to do so.