Singleton

Synchronized Pattern

public class Singleton {
    private static Singleton instance;
    private final Singleton() {};
    
    public static Singleton synchronized getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

Since the read of instance is synchronized => it cannot be made in parallel => in multicore world this is already a bad (non-performant) implementation of Singleton

Double check locking Singleton pattern

public class Singleton {
    private static Singleton instance;
    private final Singleton() {};
    private static Object key;
    
    public static Singleton getInstance() {
        if (instance != null) {
            return instance;        // 1
        }
        
        synchronized(key) {        // 2
            if (instance == null) {
                instance = new Singleton();
            }
            return instance;
        }
    }    
}

There is a bug in this implementation

  • in (1) the read is not synchronized or volatile => non synchronized read

  • in (2) the write is synchronized => synchronized write

  • Do we have a guarantee that the read will get the value set by write?

    • ⚠️for this we need happens before link

public class Singleton {
    private static volatile Singleton instance; // THIS IS A FIX! (volatile)
    private final Singleton() {};
    private static Object key;
    
    public static Singleton getInstance() {
        if (instance != null) {
            return instance;        
        }
        
        synchronized(key) {        
            if (instance == null) {
                instance = new Singleton();
            }
            return instance;
        }
    }    
}

⚠️But the fix by making an instance volatile costs the same performance prise as in synchronized Pattern above.

Enum solution

public enum Singleton {
    INSTANCE
}

Last updated