设计模式——单例模式

懒汉式

public class Singleton {
  private static Singleton instance;

  private Singleton() {
  }

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

优点:只有在使用时才会实例化单例,一定程度上节约了内存资源。

缺点:第一次加载时要立即实例化,反应稍慢。每次调用getInstance()方法都会进行同步,这样会消耗不必要的资源这种模式一般不建议使用

饿汉式

public class Singleton {
  private static Singleton instance = new Singleton();

  private Singleton() {
  }

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

优点:线程安全,不需要考虑并发安全性。

缺点:浪费内存空间,不管该对象是否被使用到,都会在启动是提前分配内存空间.

DCL双重检测锁

public class Singleton {
  private static volatile Singleton instance = null;

  private Singleton() {
  }

  public static Singleton getInstance() {
    // 两层判空,第一层是为了避免不必要的同步
    if (instance == null) {
      synchronized (Singleton.class) {
        if (instance == null) {// 第二层是为了在null的情况下创建实例
          instance = new Singleton();
        }
      }

    }
    return instance;
  }
}

优点:资源利用率高,既能够在需要的时候才初始化实例,又能保证线程安全,同时调用getInstance()方法不进行同步锁,效率高。

缺点:第一次加载时稍慢,由于Java内存模型的原因偶尔会失败。在高并发环境下也有一定的缺陷,虽然发生概率很小。

静态内部类

public class Singleton {
  private Singleton() {
  }

  public static Singleton getInstance() {
    return SingletonHolder.instance;
  }

  /**
    * 静态内部类
    */
  private static class SingletonHolder {
    private static Singleton instance = new Singleton();
  }
}

优点:

  • 对象的创建是线程安全的。
  • 支持延时加载。
  • 获取对象时不需要加锁

基于枚举实现

public class Singleton {
  private Singleton(){
  }

  public static enum SingletonEnum {
    SINGLETON;
    
    private Singleton instance = null;
    
    private SingletonEnum(){
      instance = new Singleton();
    }
    
    public Singleton getInstance(){
      return instance;
    }
  }
}

基于容器实现

public class SingletonManager {
  private static Map<String, Object> objMap = new HashMap<String, Object>();

  public static void regsiterService(String key, Object instance) {
    if (!objMap.containsKey(key)) {
      objMap.put(key, instance);
    }
  }

  public static Object getService(String key) {
    return objMap.get(key);
  }
}

SingletonManager可以管理多个单例类型,在程序的初始化时,将多个单例类型注入到一个统一管理的类中,使用时根据key获取对象对应类型的对象。这种方式可以通过统一的接口获取操作,隐藏了具体实现,降低了耦合度。


欢迎小伙伴们积极指正和讨论,一起共同成长。

posted @ 2022-10-29 23:18  咖啡因的取悦  阅读(21)  评论(0)    收藏  举报