美文网首页
单例模式(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