zoukankan      html  css  js  c++  java
  • 单例的最佳实践!!

    http://en.wikipedia.org/wiki/Singleton_pattern

    Lazy initialization[edit source | editbeta]

    This method uses double-checked locking, which should not be used prior to J2SE 5.0, as it is vulnerable to subtle bugs. The problem is that an out-of-order write may allow the instance reference to be returned before the Singleton constructor is executed.[8]

    public class SingletonDemo {
            private static volatile SingletonDemo instance = null;
     
            private SingletonDemo() {       }
     
            public static SingletonDemo getInstance() {
                    if (instance == null) {
                            synchronized (SingletonDemo .class){
                                    if (instance == null) {
                                            instance = new SingletonDemo ();
                                    }
                            }
                    }
                    return instance;
            }
    }
    

    There is much simpler and cleaner version, however:

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

    Eager initialization[edit source | editbeta]

    If the program will always need an instance, or if the cost of creating the instance is not too large in terms of time/resources, the programmer can switch to eager initialization, which always creates an instance:

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

    This method has a number of advantages:

    • The instance is not constructed until the class is used.
    • There is no need to synchronize the getInstance() method, meaning all threads will see the same instance and no (expensive) locking is required.
    • The final keyword means that the instance cannot be redefined, ensuring that one (and only one) instance ever exists.

    Static block initialization[edit source | editbeta]

    Some authors[9] refer to a similar solution allowing some pre-processing (e.g. for error-checking). In this sense, the traditional approach could be seen as a particular case of this one, as the class loader would do exactly the same processing.

    public class Singleton {
      private static final Singleton instance;
     
      static {
        try {
          instance = new Singleton();
        } catch (IOException e) {
          throw new RuntimeException("Darn, an error occurred!", e);
        }
      }
     
      public static Singleton getInstance() {
        return instance;
      }
     
      private Singleton() {
        // ...
      }
    }
    

    The solution of Bill Pugh[edit source | editbeta]

    University of Maryland Computer Science researcher Bill Pugh has written about the code issues underlying the Singleton pattern when implemented in Java.[10] Pugh's efforts on the "Double-checked locking" idiom led to changes in the Java memory model in Java 5 and to what is generally regarded as the standard method to implement Singletons in Java. The technique known as the initialization on demand holder idiom, is as lazy as possible, and works in all known versions of Java. It takes advantage of language guarantees about class initialization, and will therefore work correctly in all Java-compliant compilers and virtual machines.

    The nested class is referenced no earlier (and therefore loaded no earlier by the class loader) than the moment that getInstance() is called. Thus, this solution is thread-safe without requiring special language constructs (i.e. volatile or synchronized).

    public class Singleton {
            // Private constructor prevents instantiation from other classes
            private Singleton() { }
     
            /**
            * SingletonHolder is loaded on the first execution of Singleton.getInstance() 
            * or the first access to SingletonHolder.INSTANCE, not before.
            */
            private static class SingletonHolder { 
                    public static final Singleton INSTANCE = new Singleton();
            }
     
            public static Singleton getInstance() {
                    return SingletonHolder.INSTANCE;
            }
    }
    
  • 相关阅读:
    维基百科可以浏览了,不能搜索
    《语言的本能》很值得一读
    打算尝试瑜伽,看是否能解决长期困扰的胃痛问题
    折腾了一晚终于把rails安装好了!
    世界杯正在成为鸡肋!球迷越来越像傻瓜!
    第一次愉快的通过豆瓣购书
    我对少林方丈释永信的一点初浅看法
    myet: 练习英语口语不错
    蚂蚁社区和胃病治疗诀窍
    装好了ubuntu,w2k却无法启动了,:(
  • 原文地址:https://www.cnblogs.com/riskyer/p/3310832.html
Copyright © 2011-2022 走看看