属于创建型模式 (共5种)
共有8种写法
平时使用中 spring的bean工厂可以保证单例
1、饿汉式 01
构造方法私有 实例属性 private static final 修饰 直接 初始化 new instance 静态get instance方法返回实例
2、饿汉式02
在饿汉式01的基础上 加入静态代码块 在代码块中 new instance 完成初始化实例
3、懒汉式01 (线程不安全)
构造方法私有 实例属性私有且静态 在在静态方法 get instance 中判断实例是否为空 不为空直接 return 为空 new instance 
4、懒汉式02 (线程安全)但是效率降低
在lazy01的基础上 获取实例的方法 用 synchronized 保证了线程安全
5、懒汉式03(线程不安全)
试图通过减小同步代码块的方式提高效率 在获取实例方法 判断实例是否为空下方加入 synchronized 代码块 但是判断和代码块没有进行一体化操作 导致线程不安全
6、懒汉式04(线程安全)
在lazy03的基础上 进行了双判断 代码块中再次进行判断实例是否为空 实例属性中加 volatile 修饰
防止指令重排 同使初始化对象刷新可见
保证了线程安全
加volatile原因
创建对象的过程 1分配内存空间 2创建实例对象 3把内存地址赋值给变量的引用
如果不佳volatila 指令可能会重拍序 1 3 先执行完 再执行2
1 3 执行完 有一个请求进入 判断实例的引用不为空 会直接返回实例引用 (实际事例对象没有创建)
事例引用 调实例方法就会报错
7、静态内部类(JVM保证单例)属于懒加载
在类中 新建静态内部类 private static class 在静态内部类中采用饿汉式01的方式初始化实例
外部类构造方法私有 内部类可以初始化实例 getInstance 方法中 返回内部类初始化的实例
原理 外部类加载的时候内部类 不会加载 可以实现懒加载
虚拟机加载class的时候只加载一次 保证线程安全
8、枚举单例 (不仅可以解决线程同步 还可以防止反序列化)
一个枚举类 enum 中只有一个取值 INSTANCE 
Java 反射 可以通过 类名.class 将类漏到内存 在用过 new instance 的方式新建实例
枚举类不会被反序列化 因为枚举类没有构造方法 即使拿到了Class文件 也没办法构造他的对象
反序列化返回的只是 枚举类中的一个值 根据这个值在查产生的对象 返回的是和单例产生的同一个对象
