23
MayHow to Use Singleton Pattern in Java with Easy Examples
Have you ever tried using a printer at home or in an office where everyone needs access to just one shared device? Imagine what would happen if every person created their new printer – messy, right? Instead, everyone uses the same single printer. This idea of 'one and only one instance' is exactly what the Singleton Design Pattern is all about in Java.
In this Design Pattern tutorial, we simplify the Singleton Design Pattern in Java and break it down in an easy, understandable way.
What is the Singleton Design pattern in Java?
The Singleton Design Pattern in Java ensures that a class has only one instance and provides a single point to access that instance. It is useful for situations where only one object is needed, like managing a shared resource.
Key Points to Remember for Singleton Design Pattern
- The Singleton Design Pattern in Java ensures that only one object of a class is created.
- It gives a single point of access to that object across the application.
- The Singleton Design Pattern in Java helps manage shared resources, like a database connection.
- It saves memory and improves performance by avoiding the creation of multiple objects.
- The pattern ensures consistency by using the same instance everywhere in the application.
UML Diagram of Singleton Design Pattern in Java
We will examine the UML diagram of the Singleton Design Pattern in Java to understand how it works. This diagram will help you see the structure and how the class controls a single object.
If you haven't checked our basic Design Patterns and their types in Java, please check this out once- Learn Design Patterns in Java: Types, Examples, and Applications.
How to Implement the Singleton Design Pattern in Java
We will learn how to create only one object of a class using the Singleton Design Pattern in Java. This easy example will help you understand the Singleton Design Pattern in Java step by step. There are three main ways to implement the Singleton Design Pattern in Java, each with its own steps and use cases.
- Lazy Initialization (Non-thread-safe)
- Eager Initialization
- Thread-safe Singleton (with synchronized)
1. Lazy Initialization (Non-thread-safe)
Lazy Initialization (Non-thread-safe) in the Singleton Design Pattern in Java creates the instance only when it is needed, which saves resources. In this approach, the Singleton Design Pattern in Java ensures that only one instance is created, but it is not thread-safe, meaning it can lead to issues in multi-threaded environments.
Let's go through each step and see how it works!
Step 1: Declare a private static variable of the same class
In this step, you declare a private static variable inside the class that holds the instance of the Singleton Design Pattern in Java. This variable will hold a single instance of the class.
private static Singleton instance;
This ensures that the Singleton Design Pattern in Java can only have one instance throughout the application. The instance is initially set to null.
Step 2: Make the constructor private
Java's constructors are made private so that no other class can create an object of the Singleton Design Pattern directly. This ensures that only the class itself can create and manage the instance.
private Singleton() {}
By making the constructor private, you restrict any external code from instantiating the class. The only way to get an instance is through the public static method.
Step 3: Create a public static method to return the instance
The public static method checks if the instance is null and creates the object only if needed. This method provides a global access point for the Singleton Design Pattern in Java.
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton(); // Create the instance if not already created
}
return instance;
}
The static getInstance() method is used to access the Singleton Design Pattern in Java. If the instance is null, it creates the object; otherwise, it returns the existing instance.
Full Code Example
Here’s the full code example of the Singleton Design Pattern in Java, showing how to implement it step by step.
public class Singleton {
// Step 1: Declare a private static variable of the same class
private static Singleton instance;
// Step 2: Make the constructor private
private Singleton() {}
// Step 3: Create a public static method to return the instance
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton(); // Create the instance if not already created
}
return instance;
}
}
This approach is simple but not thread-safe, which means it could lead to issues if multiple threads try to create the instance at the same time.
Advantages of Lazy Initialization (Non-thread-safe)
- Efficient Memory: The Instance is created only when needed, saving memory.
- Faster Startup: No initial object creation, leading to quicker app startup.
- Delayed Creation: The Instance is created only when it's actually required.
Disadvantages of Lazy Initialization (Non-thread-safe)
- Not Thread-Safe: Can cause issues in multi-threaded environments.
- Multiple Instances: Threads may create different instances.
- Race Conditions: Risk of simultaneous access leading to errors.
2. Eager Initialization
In the Singleton Design Pattern in Java, Eager Initialization creates the instance at the time of class loading. This approach ensures that the Singleton Design Pattern in Java is available as soon as the class is loaded into memory.
Let's go through each step and see how it works!
Step 1: Create a private static final instance
In this step, you declare a private static final variable that holds the single instance of the class. The instance is created when the class is loaded, ensuring that it is always available and preventing any other instance from being created.
private static final Singleton instance = new Singleton();
This variable ensures that the Singleton Design Pattern in Java has only one instance. The instance is created at the time of class loading, meaning it is eagerly initialized. The final keyword ensures that the instance cannot be modified after creation.
Step 2: Make the constructor private
The constructor is made private to prevent other classes from creating an object of the class. This ensures that only the class itself can manage the creation of the Singleton Design Pattern in Java.
private Singleton() {}
By making the constructor private, you restrict external classes from directly creating instances. The only way to access the Singleton Design Pattern in Javais through the public static method defined in the next step.
Step 3: Provide a public static method to return the instance
In this step, you provide a public static method that returns an instance of the class. Since the instance is created at class loading time, the method simply returns the existing instance.
public static Singleton getInstance() {
return instance;
}
The static method getInstance() allows global access to the single instance of the Singleton Design Pattern in Java. This ensures that the same instance is used whenever the method is called, maintaining consistency throughout the application.
Full Code Example
Here’s the full code example of the Singleton Design Pattern in Java, showing how to implement it step by step.
public class Singleton {
// Step 1: Create a private static final instance
private static final Singleton instance = new Singleton();
// Step 2: Make the constructor private
private Singleton() {}
// Step 3: Provide a public static method to return the instance
public static Singleton getInstance() {
return instance;
}
}
The Eager Initialization method is thread-safe and guarantees that the Singleton Design Pattern in Java instance is created only once.
Advantages of Eager Initialization
- Thread-Safe: The instance is created when the class is loaded, making it thread-safe.
- Simple Implementation: Easy to implement without needing extra logic.
- No Synchronization Overhead: No performance cost from synchronization.
Disadvantages of Eager Initialization
- High Memory Usage: The instance is created even if it’s never used.
- No Lazy Loading: The instance is created at startup, even if not needed.
- Less Flexibility: No option to delay the instance creation.
3. Thread-Safe Singleton using Synchronized Method
In the Singleton Design Pattern in Java, the Thread-Safe Singleton using Synchronized Method ensures that only one thread can create the instance at a time. This way makes the Singleton Design Pattern in Java safe to use in multi-threaded environments.
Let's go through each step and see how it works!
Step 1: Create a private static instance variable
You declare a private static variable inside the class that will hold the single instance of the class. At first, it is set to null.
private static Singleton instance;
This step is the base of the Singleton Design Pattern in Java. The variable is shared across all calls and is used to store the only instance of the class.
Step 2: Make the constructor private
You make the constructor private to stop other classes from creating objects directly. Only this class will be able to manage the instance creation.
private Singleton() {}
This step ensures full control over object creation in the Singleton Design Pattern in Java. Ithelpskeepthe instance private and protected from unwanted instantiation.
Step 3: Create a synchronized public static method to return the instance
You define a public static method that checks if the instance is null. If yes, it creates the object. The method is marked synchronized to make sure only one thread can execute it at a time.
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
This step is very important in the Singleton Design Pattern in Java because it makes the method thread-safe. In multi-threaded programs, it ensures that only one instance is created and shared, avoiding duplication.
Full Code Example
Here’s the full code example of the Singleton Design Pattern in Java, showing how to implement it step by step.
public class Singleton {
// Step 1: Create a private static instance variable
private static Singleton instance;
// Step 2: Make the constructor private
private Singleton() {}
// Step 3: Create a synchronized public static method to return the instance
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
- This method of the Singleton Design Pattern in Java uses synchronization to make sure no two threads create separate instances.
- It’s a simple and effective way to implement thread-safe code.
- Though slightly slower due to synchronization, it guarantees that only one object of the Singleton Design Pattern in Java is ever created.
Advantages of Thread-Safe Singleton using Synchronized Method
- Thread-Safe: Ensures only one instance is created, even in multi-threaded environments.
- Lazy Initialization: The instance is created only when needed, saving resources
- Controlled Access: Synchronization ensures safe access to the instance from multiple threads.
Disadvantages of Thread-Safe Singleton using Synchronized Method
- Slower Performance: Synchronization can slow down access in multi-threaded use.
- Every Call is synchronized: Even after the instance is created, all calls are still synchronized.
- Less Efficient: Not the best choice when high performance is needed.
Selecting the Best Singleton Pattern for Your Need
Choosing the correct Singleton Design Pattern in Java depends on how your application works with memory, threads, and performance. The Singleton Design Pattern in Java is useful when you want only one object of a class to exist, but how you implement it can vary based on your needs.
1. Use Eager Initialization when:
- The Singleton Design Pattern in Java is always required.
- You don’t need lazy loading.
- Simplicity and thread safety are more important than memory usage.
2. Use Lazy Initialization (Non-thread-safe) when:
- You're in a single-threaded setup
- You want the Singleton Design Pattern in Java to be created only when needed.
- You prefer lower memory use and quick startup.
3. Use a Thread-Safe Singleton using the Synchronized Method when:
- You work in a multi-threaded environment.
- You want the Singleton Design Pattern in Java to be both lazy-loaded and thread-safe.
- You're okay with a slight performance loss for safer code.
So, based on your project size and structure, pick the Singleton Design Pattern in Java approach that offers the right balance of safety, speed, and simplicity.
Conclusion
In conclusion, understanding the Singleton Design Pattern in Java is no longer confusing. With the different approaches in mind, you can now choose the one that fits your project with confidence. It’s a great feeling when complex things start to feel simple, and you’ve just done that! Boost your coding skills with our Free Java Course offered by ScholarHat, which is the easiest way to start your Java journey!
Further Read Articles: |
Gang of Four Design Patterns |
Builder Design Pattern |
Understanding the Composite Design Pattern |
Test your skills with the following MCQs
Ready to test your understanding of the Singleton design pattern? Let’s go!