Singleton pattern with combination of lazy loading and thread safety

前端 未结 5 2011
天涯浪人
天涯浪人 2021-02-03 23:53

I was doing some research about singletons, specifically regarding lazy vs eager initialization of singletons.

An example of eager initialization:

public         


        
5条回答
  •  半阙折子戏
    2021-02-03 23:55

    In my opinion, this is an inappropriate pattern to use. It makes assumptions about the JVM's behavior which are non-trivial and confusing. Also, it has a dummy class. Dummy classes should be avoided when possible.

    I suggest the straightforward approach:

    public class Foo {
        private volatile static final Foo instance = null;
    
        private Foo() {
        }
    
        public static Foo instance() {
            if (instance == null) instance = new Foo();
            return instance;
            }
        }
    }
    

    ... although, this does not work as-is - it's not thread safe.. What you really want is the double-check pattern presented in Item 71 of Bloch's Effective Java; see here. Adapting the example at the link to your case, we get:

    public class Foo {
        private volatile static final Foo instance = null;
    
        private Foo() {
        }
    
        public static Foo instance() {
            if (instance != null) return instance;
            synchronized(instance) {
               Foo result = instance;
               if (instance == null) {
                    result = instance = new Foo();
               return result;
            }
        }
    }
    

    Notes:

    • Don't worry about the performance of this code, modern JVMs take care of it and it's just fine. After all, premature optimization is the root of all evil.
    • As is suggested in other answers, the above is not Bloch's preferred solution, but I think using an enum for a singleton is semantically inappropriate just like what OP did originally.

提交回复
热议问题