1. 饿汉式

// 饿汉式public class Singleton {    private static Singleton INSTANCE = new Singleton();    private Singleton() {}    public static Singleton getInstance() {        return INSTANCE;    }}

2. 懒汉式

public class Singleton {    private static Singleton INSTANCE;    private Singleton() {}    public static Singleton getInstance() {        if (INSTANCE == null) {            INSTANCE = new Singleton();                    }        return INSTANCE;    }}

3. 线程平安懒汉式-双重查看

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

4. 双重查看的不足之处

以下三种状况会毁坏双重查看的单例模式:指令重排序、序列/反序列化、反射

4.1 指令重排序

INSTANCE = new Singleton()语句并非原子操作,分为以下三步:

  1. 调配Singleton对象内存空间。
  2. 初始化对象。
  3. 将INSTANCE对象援用指向调配的内存空间。

因为指令重排序的问题,以上指令在理论状况可能以1 -> 3 -> 2的程序执行。
在多线程的状况下可能呈现:

执行程序线程 A线程 B
1调配Singleton对象内存空间
2将INSTANCE对象援用指向调配的内存空间
3拜访getInstance()办法,判断INSTANCE对象是否为null
4因为INSTANCE曾经实现了对象援用指向,因为不为null,但此时INSTANCE还没有实现初始化
5初始化对象
6拜访INSTANCE援用的对象

解决办法:
应用volatile润饰INSTANCE对象

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

4.2 序列/反序列化毁坏单例

参考大佬文章:https://segmentfault.com/a/11...

如果想要避免单例被序列/反序列化毁坏。就让单例类实现readResolve()办法。

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

4.3 反射毁坏单例

参考大佬文章:https://segmentfault.com/a/11...
为了避免反射毁坏单例,采纳枚举实现单例模式。

public enum EnumSingleton {    INSTANCE;     public EnumSingleton getInstance(){          return INSTANCE;    }}
参考文献
https://www.liaoxuefeng.com/w...
https://segmentfault.com/a/11...