单例模式的几种写法

什么是单例模式

单例模式,又称单子模式,指的是一个类只有一个实例,并且提供一个全局访问点。

它具有以下特征:

  • 私有的构造方法
  • 指向自己实例的私有静态引用
  • 以自己实例为返回值的静态的公有的方法

单例模式的几种写法

饿汉式

public class Singleton{
  private Singleton() {}
  private final static Singleton mInst = new Singleton();

  public static Singleton getInstance(){
      return mInst;
  }
}

该写法在类装载时就进行创建,天生是线程安全的。但是如果构造方法中存在过多处理则会影响性能。

懒汉式

public class Singleton{
  private Singleton() {}
  private static Singleton mInst;

  public static Singleton getInstance(){
      if(mInst == null){
          mInst = new Singleton();
    }
    return mInst;
  }
}

该写法只在单例实例第一次使用的时候创建,但并不是线程安全的,会在多线程的情况下存在多次实例化的情况。

所以在考虑多线程的情况下,加入同步锁:

public class Singleton{
  private Singleton() {}
  private static Singleton mInst;

  public static synchronized Singleton getInstance(){
      if(mInst == null){
          mInst = new Singleton();
    }
    return mInst;
  }
}

虽然加入了synchronized关键字后可以保证线程的安全,但是在每次调用Singleton.getInstance()都进行同步会造成很多不必要的开销,消耗资源。

双重校验锁

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

该写法在保证只在使用的时候进行初始化单例,同时也保证了线程的安全,并且降低了资源的耗费。

静态内部类

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

该写法是Singleton类被装载了,但INSTANCE不一定被初始化。因为SingletonHolder类没有被主动使用,只有显示通过调用getInstance()方法时,才会显示装载SingletonHolder类,从而实例化INSTANCE

版权声明:

本文标题:单例模式的几种写法

作者:Rabtman

原始链接:https://rabtman.com/2016/04/11/writing_singleton/

本文采用署名-非商业性使用-禁止演绎4.0进行许可。

非商业转载请保留以上信息。商业转载请联系作者本人。