How to Use Singleton Pattern in Java with Easy Examples

How to Use Singleton Pattern in Java with Easy Examples

20 May 2025
Advanced
13 Views
21 min read

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.

Singleton Design Pattern in Java

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.

  1. Lazy Initialization (Non-thread-safe)
  2. Eager Initialization
  3. 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!

    Q 1: What is the main purpose of the Singleton design pattern?

    • Ensure a class has only one instance
    • Allow multiple instances of a class
    • Restrict the use of inheritance
    • None of the above

    FAQs

    It is useful when you need a single, shared instance for tasks like managing database connections, logging, or configuration settings.

    No, only specific implementations like eager initialization or synchronized methods ensure thread safety. Lazy initialization without synchronization is not thread-safe.

    It can make unit testing difficult, introduce hidden dependencies, and sometimes lead to memory issues if not used correctly.

    Ideally, no. But improper implementation, reflection, or deserialization can create multiple instances unless prevented. 

    A Singleton allows object creation and can implement interfaces, whereas a static class only contains static methods and cannot be instantiated. 
    Share Article
    About Author
    Shailendra Chauhan (Microsoft MVP, Founder & CEO at ScholarHat)

    Shailendra Chauhan, Founder and CEO of ScholarHat by DotNetTricks, is a renowned expert in System Design, Software Architecture, Azure Cloud, .NET, Angular, React, Node.js, Microservices, DevOps, and Cross-Platform Mobile App Development. His skill set extends into emerging fields like Data Science, Python, Azure AI/ML, and Generative AI, making him a well-rounded expert who bridges traditional development frameworks with cutting-edge advancements. Recognized as a Microsoft Most Valuable Professional (MVP) for an impressive 9 consecutive years (2016–2024), he has consistently demonstrated excellence in delivering impactful solutions and inspiring learners.

    Shailendra’s unique, hands-on training programs and bestselling books have empowered thousands of professionals to excel in their careers and crack tough interviews. A visionary leader, he continues to revolutionize technology education with his innovative approach.
    Accept cookies & close this