单例模式
2026/8/24大约 1 分钟
单例模式
保证一个类仅有一个实例,并提供一个访问它的全局访问点。
定义与功能
- 保证:类在运行期间只创建一个实例
- 访问点:
getInstance()全局唯一入口 - 范围:单例范围是"一个虚拟机"(类装载由虚拟机完成)
两种基本实现
| 类型 | 实现 | 特点 |
|---|---|---|
| 饿汉式 | private static Singleton instance = new Singleton(); | 线程安全(虚拟机保证类只装载一次),空间换时间 |
| 懒汉式 | private static Singleton instance = null; | 延迟加载,时间换空间,不加同步线程不安全 |
懒汉式线程安全方案
1. 直接加同步
public static synchronized Singleton getInstance() {}缺点:每次访问都要同步,降低速度。
2. 双重检查锁(DCL)
public class Singleton {
private volatile static Singleton instance = null;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) { // 第一重检查(先不同步)
synchronized (Singleton.class) {
if (instance == null) { // 第二重检查
instance = new Singleton();
}
}
}
return instance;
}
}volatile保证变量不被本地线程缓存,读写直接操作共享内存- 双重检查:并非每次进入都同步,先检查实例是否存在,不存在才进入同步块
3. 静态内部类(推荐)
public class Singleton {
private Singleton() {}
/** 类级内部类,只有被调用时才装载,实现延迟加载 */
private static class SingletonHolder {
/** 静态初始化器,由 JVM 保证线程安全 */
private static final Singleton instance = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.instance;
}
}利用 JVM 类加载机制天然保证线程安全,同时具备延迟加载特性。