How would you implement a thread-safe Singleton in Java?

A thread-safe Singleton guarantees only one instance of a class is ever created even when multiple threads request it concurrently. In Java, the most common efficient approach is the initialization-on-demand holder idiom, which relies on class-loading guarantees instead of explicit synchronization.

Key Points: • The JVM guarantees a class is initialized exactly once, and only when it's first referenced, which the holder idiom exploits. • The Singleton instance lives inside a private static inner class that isn't loaded until getInstance() is called. • No synchronized keyword is needed, so there's no ongoing locking overhead after initialization. • Alternatives include an eager static final field, double-checked locking with a volatile field, or an enum-based Singleton. • Enum Singletons are the simplest fully safe option since Java also protects them against reflection and serialization attacks.

Example: A ConfigurationManager that reads settings from disk once and shares them across the application is a good Singleton candidate, since re-reading configuration per thread would be wasteful and could cause inconsistent state.

Code Example:

public class ConfigurationManager {

    private ConfigurationManager() {
        // load configuration
    }

    private static class Holder {
        private static final ConfigurationManager INSTANCE = new ConfigurationManager();
    }

    public static ConfigurationManager getInstance() {
        return Holder.INSTANCE;
    }
}

Interview Tip: A concise interview answer is:

"I implement thread-safe Singletons with the initialization-on-demand holder idiom: a private static inner class holds the instance, and the JVM's class-loading guarantees make it lazy and thread-safe without any explicit synchronization. For very simple cases I'd just use an enum, since it's inherently safe against reflection and serialization."