该模式涉及到一个单一的类,该类负责创建自己的对象,并确保只有单个对象被创建。同时,该类提供了一种访问其唯一对象的方式。
单例模式分为两种:
饿汉式:类加载就会导致单实例对象被创建
懒汉式:类加载不会导致单实例对象被创建,首次使用该对象时才会创建
饿汉式
静态变量 & 静态代码块
public class Singleton {
private Singleton() {}
private static Singleton instance = new Singleton();
public static Singleton getInstance() { return instance; }
}
public class Singleton {
private Singleton() {}
private static Singleton instance;
static {
instance = new Singleton();
}
public static Singleton getInstance() { return instance; }
}
在上述实现中,instance 对象是随着类的加载而创建的,如果一直没有使用,则会造成内存浪费。
枚举
public enum Singleton {
INSTANCE;
}
上述实现非常简洁,同时也是实现单例模式最安全、最推荐的方式。
懒汉式
双重检查 + volatile
public class Singleton {
private Singleton() {}
private static volatile Singleton instance;
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
在上述实现中,通过 synchronized 保证线程安全;通过双重检查提升性能(否则,每个线程必须持有锁才能调用 getInstance 方法);通过 volatile 禁止指令重排序,解决双重检查带来的空指针异常问题。
静态内部类
public class Singleton {
private Singleton() {}
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
上述实现通过类加载机制,在没有加锁的情况下,保证了线程安全,具有更好的性能,是开源项目中比较常用的一种对单例模式的实现。
参考:https://www.bilibili.com/video/BV1Np4y1z7BU/?spm_id_from=333.337.search-card.all.click