Java Concurrency Interview

Patterns and antipatterns question 159 of 180 mid

What are the thread-safe ways to write a singleton, and which would you pick?

The JVM initializes a class exactly once, under a lock, and everything the static initializer writes is visible to every thread that uses the class afterwards. Three of the good answers are just ways of borrowing that lock:

final class Config {
    private Config() { }

    private static final class Holder {
        static final Config INSTANCE = new Config();   // runs on the first call to get()
    }

    static Config get() {
        return Holder.INSTANCE;
    }
}

enum Registry {
    INSTANCE;

    private final Map<String, String> entries = new ConcurrentHashMap<>();

    String lookup(String key) {
        return entries.get(key);
    }
}

Pick the holder or the enum. Then say the part people forget: a thread-safe singleton is not a thread-safe object. One instance shared by every thread needs its own state guarded, which is why the enum above uses a ConcurrentHashMap. And a static initializer that reaches into another class whose initializer reaches back can deadlock two threads on class initialization, a hang with no synchronized anywhere in the source.

singleton patterns class-initialization

Quiz yourself on Patterns and antipatterns Suggest a correction