How to write a Singleton in proper manner?

后端 未结 13 1099
走了就别回头了
走了就别回头了 2020-12-23 12:03

Today in my interview one interviewer asked me to write a Singleton class. And i gave my answer as

public class Singleton {

    private static Singleton re         


        
相关标签:
13条回答
  • 2020-12-23 12:50

    As others have already pointed out, the enum pattern is now widely considered a better approach to the Singleton vs. the old-school method, but I just wanted to point out a drawback.

    We had a Singleton in the form of:

    public enum Foo {
        INSTANCE;
    }
    

    that had been around for awhile, working just fine. Then during a code review, we saw this:

    public enum Foo {
        INSTANCE,
        ANOTHER;
    }
    

    After we smacked him across the face with a wet mackerel, the coder in question had seen the error of his ways, and a larger than small amount of code had to be backed out and/or rewritten. Yes, we caught it before it went out into production, but work had to be done to erase it.

    I feel that this a weakness of this type of Singleton (albeit small and perhaps rare) vs. the old-school way. Yes, you can break any pattern by implementing it wrong, but it seems a whole heck of a lot easier for a coder to break an enum Singelton than a well-formed old-school Singleton.

    EDIT:

    For completeness, here's an enum Singleton that guards against additional values getting added later:

    public enum Foo
    {
      INSTANCE;
      // adding another type here will cause a runtime
    
      static
      {
        if (Foo.values().length != 1)
        {
          throw new IllegalStateException("Not a Singleton.");
        }
      }
    }
    
    0 讨论(0)
  • 2020-12-23 12:52

    Why can't you do just

    public class SingletonSandBox {
    
        private static SingletonSandBox instance = new SingletonSandBox();
    
        private SingletonSandBox(){
        }
    
        public static SingletonSandBox getInstance(){
            return instance;
        }
    
    }
    

    and test

    public static void main(String[] args) {
    
            SingletonSandBox sss1 = SingletonSandBox.getInstance();
    
            SingletonSandBox sss2 = SingletonSandBox.getInstance();
    
            System.out.println(sss1 == sss2);
    
    }
    

    As I know this is thread-safe and shorter than using static block. Again static field declaration is read earlier comparing to static block by the runtime.

    0 讨论(0)
  • 2020-12-23 12:56

    You can do

    public enum Singleton {
        INSTANCE;
    }
    

    and for a utility class which has no instances

    public enum Utility {
         ;
    
         public static void method();
    }
    
    0 讨论(0)
  • 2020-12-23 12:56

    A thread safe version of the OPs initial approach, plus no one else dared to suggest a synchronized statement.

    final class Singleton
    {
        private static Object lock = new Object();
        private static volatile Singleton instance = null;
        private Singleton() { }
        public static Singleton getInstance()
        {
            if(instance == null)
            {
                synchronized(lock)
                {
                    if(instance == null)
                    {
                        instance = new Singleton();
                    }
                }
            }
            return instance;
        }
    }
    
    0 讨论(0)
  • 2020-12-23 12:58

    This is because your solution is not threadsafe.

    The modern way is to tie the instance to an enum value:

    enum Singleton {
        INSTANCE;
    }
    

    If you want to use lazy init of the instance then you can use the ClassLoader to guarantee thread safety:

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

    More information on Wikipedia

    0 讨论(0)
  • 2020-12-23 12:59

    The Singleton I'd write would look like this:

    @Service
    class PersonService {
        // implementation here
    }
    

    But I also like the enum ideas. In reality, I never write (nor need) a Singleton other than one like the one above.

    0 讨论(0)
提交回复
热议问题