java实现单例模式的各种写法

饿汉式

public class SingletonObject1 {

  private SingletonObject1() {
  }

  private static final SingletonObject1 INSTANCE = new SingletonObject1();

  public static SingletonObject1 getInstance() {
    return INSTANCE;
  }

}

线程安全,类加载时就创建实例,java内部就使用到了这种方式。


双重锁判断

public class SingletonObject2 {

  private SingletonObject2() {
  }

  private static volatile SingletonObject2 INSTANCE;

  public static SingletonObject2 getInstance() {
    if (INSTANCE == null) {
      synchronized (SingletonObject2.class) {
        if (INSTANCE == null) {
          INSTANCE = new SingletonObject2();
        }
      }
    }
    return INSTANCE;
  }

}

new一个对象之后,这个对象可能还没有完全构造成功,另外的线程使用就可能出问题,volatile关键字可以禁止指令重排序,避免此问题。


Spring中的ReactiveAdapterRegistry和DefaultConversionService都使用到了这种方式。

静态内部类

public class SingletonObject3 {

  private SingletonObject3() {
  }

  private static class SingletonObject3Holder {

    private static final SingletonObject3 INSTANCE = new SingletonObject3();
  }

  public static SingletonObject3 getInstance() {
    return SingletonObject3Holder.INSTANCE;
  }

}

jvm保证线程安全性,延迟加载,推荐使用。

枚举

public enum SingletonObject4 {

  INSTANCE;

  public static SingletonObject4 getInstance() {
    return INSTANCE;
  }

}

jvm保证线程安全,并且可以防止反射攻击,克隆攻击和反序列化攻击。



总结

单例模式的本质就是控制实例数量,可以扩展到多例。

posted @ 2021-05-05 09:11  strongmore  阅读(213)  评论(0编辑  收藏  举报