Skip to content

singleton单例

1.饿汉式

  • 类加载到内存后,就实例化一个单例,JVM保证线程安全
  • 简单实用,推荐使用!
  • 唯一缺点:不管用到与否,类装载时就完成实例化

2.懒汉式

  • 虽然达到了按需初始化的目的,但却带来线程不安全的问题
  • 可以通过synchronized解决,但也带来效率下降
  • 需双重判断,是最常用的单例

小tips:

//禁止指令重排序,当一个线程修改了这个变量的值,volatile 保证了新值能立即同步到主内存,以及每次使用前立即从主内存刷新
private static volatile Mgr06 INSTANCE;

volatile关键字参考链接:https://qtbk.xyz/?p=844

3.静态内部类方式

  • 内部类在类加载的时候不会被实例化,实现懒加载的方式,同时类加载的时候是线程安全的,类的静态属性只会在第一次加载时初始化,JVM在帮助我们保证了线程的安全性,推荐使用。

4.枚举单例

  • 不仅可以解决线程同步,还可以防止反序列化,fastjson就采用的这种方式
  • 我所知最完美的单例
  • 其他例子在不考虑反射的情况下可用,但是如果说使用反射可以创建出新的实例,而枚举单例能避免这种情况。
  • 在使用反射时枚举单例会报Exception in thread "main" java.lang.NoSuchMethodException。出现这个异常的原因是因为EnumSingleton.class.getDeclaredConstructors()获取所有构造器,会发现并没有我们所设置的无参构造器,只有一个参数为(String.class,int.class)构造器,而且在反射在通过newInstance创建对象时,会检查该类是否ENUM修饰,如果是则抛出异常,反射失败。所以枚举是不怕反射``攻击的

Comments