Yandex

Java Advanced ConceptsJava Advanced Concepts3

Java ReferenceJava Reference1

Java Singleton Class
What, Why and How to Use It



In Java, a Singleton class is a class that allows only one instance of itself to be created—and gives access to that single instance. It’s a widely used design pattern, especially when you need exactly one object to coordinate actions across the system.

Why Use a Singleton?

Imagine you're logging actions throughout your application. Would you want multiple loggers writing randomly? Of course not. A singleton logger ensures consistent behavior and state—no matter where it’s used.

How to Implement a Singleton Class in Java

Let’s go through different ways to implement a singleton class. Each method has its own nuances, especially in multi-threaded environments.

1. Eager Initialization

The instance is created at the time of class loading.

public class EagerSingleton {
    private static final EagerSingleton instance = new EagerSingleton();

    private EagerSingleton() {
        System.out.println("Instance created");
    }

    public static EagerSingleton getInstance() {
        return instance;
    }
}

Usage

public class Main {
    public static void main(String[] args) {
        EagerSingleton obj1 = EagerSingleton.getInstance();
        EagerSingleton obj2 = EagerSingleton.getInstance();
        System.out.println(obj1 == obj2); // true
    }
}
Instance created
true

Explanation

Only one object is created. Even if we try to get the instance multiple times, we get the same reference.

2. Lazy Initialization

In this approach, the instance is created only when it’s needed.

public class LazySingleton {
    private static LazySingleton instance;

    private LazySingleton() {}

    public static LazySingleton getInstance() {
        if (instance == null) {
            instance = new LazySingleton();
            System.out.println("Instance created");
        }
        return instance;
    }
}

Usage

public class Main {
    public static void main(String[] args) {
        LazySingleton obj1 = LazySingleton.getInstance();
        LazySingleton obj2 = LazySingleton.getInstance();
        System.out.println(obj1 == obj2); // true
    }
}
Instance created
true

Explanation

The object is created only when getInstance() is called the first time. It saves resources but is not thread-safe.

3. Thread-Safe Singleton (Synchronized Method)

This method ensures thread safety using synchronization.

public class ThreadSafeSingleton {
    private static ThreadSafeSingleton instance;

    private ThreadSafeSingleton() {}

    public static synchronized ThreadSafeSingleton getInstance() {
        if (instance == null) {
            instance = new ThreadSafeSingleton();
            System.out.println("Instance created");
        }
        return instance;
    }
}

Explanation

The synchronized keyword ensures that only one thread can execute this method at a time. It's safe, but might reduce performance due to synchronization overhead.

4. Double-Checked Locking (Efficient Thread-Safety)

This is a more efficient way of making the singleton thread-safe.

public class DoubleCheckedSingleton {
    private static volatile DoubleCheckedSingleton instance;

    private DoubleCheckedSingleton() {}

    public static DoubleCheckedSingleton getInstance() {
        if (instance == null) {
            synchronized (DoubleCheckedSingleton.class) {
                if (instance == null) {
                    instance = new DoubleCheckedSingleton();
                    System.out.println("Instance created");
                }
            }
        }
        return instance;
    }
}

5. Singleton Using Enum (Best Practice)

Using Enum is the simplest and most effective way to implement a singleton in Java. It prevents reflection and serialization issues.

public enum EnumSingleton {
    INSTANCE;

    public void show() {
        System.out.println("Singleton using Enum");
    }
}

Usage

public class Main {
    public static void main(String[] args) {
        EnumSingleton singleton = EnumSingleton.INSTANCE;
        singleton.show();
    }
}
Singleton using Enum

Common Mistakes to Avoid

Where is Singleton Used?

Singleton pattern is used across frameworks and applications:

QUIZ

Question 1:Which of the following implementations is considered the most effective way to create a Singleton in Java?

Question 2:Lazy initialization is thread-safe by default.

Question 3:What are some real-world use cases of the Singleton pattern?

Question 4:What is the key reason for making a Singleton constructor private?

Question 5:The double-checked locking pattern in a Singleton is used to reduce synchronization overhead.

Question 6:Which of the following are common mistakes when implementing a Singleton?



Welcome to ProgramGuru

Sign up to start your journey with us

Support ProgramGuru.org

You can support this website with a contribution of your choice.

When making a contribution, mention your name, and programguru.org in the message. Your name shall be displayed in the sponsors list.

PayPal

UPI

PhonePe QR

MALLIKARJUNA M