美文网首页
单例模式(Singleton)

单例模式(Singleton)

作者: NickelFox | 来源:发表于2017-10-15 14:04 被阅读0次

    一. 含义

    • 单例模式就是通过将构造方法设为私有,通过提供的静态getInstance方法返回某个对象的唯一实例。就是一个对象的唯一一个实例由单例类掌控。该类负责创建单例并提供全局访问点。

    二. 实现

    1. 普通单例模式
      • 实现方法:
      public class Singleton {
      
       private static Singleton sSingleton;//唯一实例
      
       /*私有构造方法,保证了外部无法创建类的实例*/
       private Singleton() {
      
       }
      
       /*通过该方法获取唯一实例*/
       public static Singleton getInstance() {
           if (sSingleton == null) {
               sSingleton = new Singleton();
           }
           return sSingleton;
       }
      }
      
      • 缺点:
        • 遇到多线程的时候就不能保证只有单一实例了

    如何解决遇到多线程时不能保证只有一个实例呢?就引出了以下方法:

    1. 加了同步锁的单例模式
      • 实现:
      public class Singleton {
      
       private static Singleton sSingleton;//唯一实例
      
       /*私有构造方法,保证了外部无法创建类的实例*/
       private Singleton() {
      
       }
      
       /*通过该方法获取唯一实例,添加了synchronized关键字,确保一次只能有一个线程执行该方法*/
       public static synchronized Singleton getInstance() {
           if (sSingleton == null) {
               sSingleton = new Singleton();
           }
           return sSingleton;
       }
      }
      
      • 缺点:
        • 其实只有当第一次创建单例是才需要互斥,后面就不用了,但是互斥锁却一直存在,严重降低性能
    2. 即刻实例化,而不是延迟实例化
      • 实现:
      public class Singleton {
      
       private static Singleton sSingleton = new Singleton();//不管用不用的到,在程序一开始就执行静态初始化,直接初始化实例,就不会存在多个实例的问题了
      
       private Singleton() {
      
       }
      
       public static Singleton getInstance() {
           return sSingleton;
       }
      }
      
      • 缺点:
        • 要是不确定用不用的到,就会造成资源浪费
    3. 双重检查加锁的单例模式
      • 实现:
      public class Singleton {
      
       private volatile static Singleton sSingleton;//volatile确保了初始化后多线程能正确处理该实例
      
       private Singleton() {
      
       }
      
       public static Singleton getInstance() {
           if (sSingleton == null) {//检查实例,若不存在就进入同步区,这样就保证了只有第一次才进行同步
               synchronized (Singleton.class) {
                   if (sSingleton == null) {
                       sSingleton = new Singleton();
                   }
               }
           }
           return sSingleton;
       }
      }
      
      • 缺点:
        • JDK1.5之前JVM对volatile关键字的实现会导致双重检查加锁失效

    三. 总结

    • 要是不考虑多线程,则第一种方式就可以实现单例模式。
    • 第二种模式严重降低性能,若对单例使用较少,影响较低则可使用
    • 第三种实现有点奇怪,但是如果能确定一定会用到单例的话,使用该方法最好。
    • 第四种实现起来较为复杂,但算是完美的解决方案了。

    相关文章

      网友评论

          本文标题:单例模式(Singleton)

          本文链接:https://www.haomeiwen.com/subject/oascextx.html