creational

Singleton

Ensure a class has only one instance and provide a global access point to it.

Some objects are meant to exist exactly once. Application config. A logger. A database connection pool.

If two parts of your code each create their own, you get two of them. Now they hold different values, or they open twice as many connections as you planned. Bugs like this are hard to spot, because each piece of code looks correct on its own.

Singleton makes the class itself responsible for this. It hides the constructor, so nobody outside can call new. Instead you ask the class for the instance, and it hands back the same one every time.

What the interviewer is probing.

1. "How do you make a singleton thread-safe in Java?" *Probing:* the implementation. *Stalls:* "Synchronise the method." *Moves up:* an enum, or a static holder class — both give lazy initialisation and thread safety without locking on every access.

2. "Why is Singleton often called an anti-pattern?" *Probing:* whether you can criticise it. *Stalls:* "It is not." *Moves up:* it is global mutable state — it hides dependencies, couples callers to the concrete class and makes tests order-dependent.

3. "What is the usual better alternative?" *Probing:* the modern answer. *Stalls:* "There is none." *Moves up:* a single instance managed by the dependency injection container, which gives one instance without the global access point.

4. "What breaks the single-instance guarantee?" *Probing:* the depth. *Stalls:* "Nothing." *Moves up:* reflection, serialisation and multiple class loaders — which is exactly why the enum form is recommended.

A country has one government — no matter who asks, they get the same governing body.

Key Concepts

1
The constructor is private. That single change means no other class can create an instance.
2
A static method is the only way in. The first call creates the object and stores it. Every call after that returns the stored one.
3
Threads make this tricky. If two threads call the method at the same moment, both may see 'not created yet' and both create one. The usual fixes are to create it eagerly when the class loads, use an enum, or use double-checked locking with a volatile field.
volatile
java
public class DatabaseConnection {
    private static volatile DatabaseConnection instance;
    private final Connection connection;

    private DatabaseConnection() {
        this.connection = DriverManager.getConnection("jdbc:postgresql://localhost/db");
    }

    public static DatabaseConnection getInstance() {
        if (instance == null) {
            synchronized (DatabaseConnection.class) {
                if (instance == null) {
                    instance = new DatabaseConnection();
                }
            }
        }
        return instance;
    }
}