Java Singleton Pattern

  • + 14 comments

    Just saying that from a completeness point of view, something like this would be required:

    class Singleton {
        private volatile static Singleton instance;
        public static String str;
        private Singleton() {}
        
        static Singleton getSingleInstance() {
            if (instance == null) {
                synchronized (Singleton.class) {
                    if (instance == null) {
                        instance = new Singleton();
                    }
                }
            }
            return instance;
        }
    
    }
    

    This utilizes the "double-checked locking" design pattern, and guarentees the following for the singleton:

    • Lazy initialization (great for resource allocation, and means we don't waste resources with eager initialization)
    • No race condition for lazy initialization (two+ more threads each trying to create a singleton will fail, guarenteed by syncronized)
    • Acquiring a lock (expensive operation) is done once and only once, thus there is no performance penalty
    • Only allows the singleton to be used when it is fully instantiated (thanks to the volatile keyword there)

    An even more clever way is this:

    class Singleton{
    	private Singleton() {}
        
        private static class SingletonHolder {
        	private static final Singleton INSTANCE = new Singleton();
        }
        
        public static Singleton getInstance() {
        	return SingletonHolder.INSTANCE;
        }
    }
    

    The second way still retains all the requirements from the first, and is just more concise. (technically speaking it's a form of lazy initialization, since it eagerly initializes on demand).

    More reading available here: cs.nyu.edu/courses/fall16/CSCI-UA.0470-001/slides/lecture25.pdf#page=52.