单例模式的变种

Java 单例模式

一、什么是单例模式

  1. 定义 :一个类在整个程序中只创建一个实例,全局共享。
  2. 核心私有构造器 + 静态获取实例方法
  3. 使用场景:工具类、配置类、线程池、日志对象、Spring Bean 等。

二、单例模式的 3 个要点

  1. 构造器私有 (禁止外部 new
  2. 自身持有静态实例
  3. 提供全局获取方式getInstance() / 枚举)

三、单例模式 6 种写法(线程安全分类)

1. 饿汉式(静态常量)

类加载就创建,天生线程安全

java 复制代码
public class Singleton {
    private static final Singleton INSTANCE = new Singleton();
    private Singleton() {}
    public static Singleton getInstance() {
        return INSTANCE;
    }
}
  • 优点:简单、安全、无锁
  • 缺点:类加载就创建,可能浪费内存
  • 线程安全:✅

2. 饿汉式(静态代码块)

和静态常量一样,只是初始化放在静态代码块

java 复制代码
public class Singleton {
    private static Singleton instance;
    static { instance = new Singleton(); }
    private Singleton() {}
    public static Singleton getInstance() {
        return instance;
    }
}

3. 懒汉式(synchronized 方法)

用的时候再创建,但加锁性能差

java 复制代码
public class Singleton {
    private static Singleton instance;
    private Singleton() {}
    public static synchronized Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}
  • 优点:懒加载
  • 缺点:并发性能极差
  • 线程安全:✅(不推荐)

4. 双重检查锁 DCL(推荐)

高性能 + 线程安全 + 懒加载

java 复制代码
public class Singleton {
    private static volatile Singleton instance;
    private Singleton() {}
    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}
  • 必须加 volatile:禁止指令重排
  • 优点:高性能、懒加载、安全
  • 线程安全:✅(推荐)

5. 静态内部类(最完美)

JVM 保证安全,懒加载,无锁

java 复制代码
public class Singleton {
    private Singleton() {}
    private static class Holder {
        private static final Singleton INSTANCE = new Singleton();
    }
    public static Singleton getInstance() {
        return Holder.INSTANCE;
    }
}
  • 外部类加载 → 不加载内部类
  • 调用 getInstance() → 才加载 Holder
  • 优点:懒加载、高性能、极简
  • 线程安全:✅(强烈推荐)

6. 枚举单例(顶级、官方推荐)

Java 语法层天生单例

java 复制代码
public enum Singleton {
    INSTANCE;

    public void method() {
        // 业务方法
    }
}

使用:

java 复制代码
Singleton.INSTANCE.method();
  • 优点:无法反射破坏、无法序列化破坏、代码最简
  • 线程安全:✅(最高级)

四、枚举单例 vs 饿汉式(核心区别)

特性 饿汉式 枚举单例
线程安全
类加载初始化
反射破坏 ❌ 可破坏 不能破坏
序列化破坏 ❌ 可破坏 不能破坏
代码量 极少
官方推荐

结论:枚举 = 终极版饿汉式


五、单例模式的 3 种破坏方式(面试重点)

  1. 反射:可调用私有构造器创建新对象
  2. 序列化/反序列化:会生成新对象
  3. 类加载器:不同类加载器可创建多个实例

只有枚举单例不会被破坏!


六、线程安全总结

写法 线程安全 懒加载 推荐指数
饿汉式 ⭐⭐⭐
懒汉式 synchronized
双重检查锁 DCL ⭐⭐⭐⭐
静态内部类 ⭐⭐⭐⭐⭐
枚举单例 ⭐⭐⭐⭐⭐

七、一句话背会(面试万能)

  1. 单例:全局一个实例,构造私有。
  2. 饿汉式:类加载创建,简单但浪费内存。
  3. DCL:必须加 volatile,禁止指令重排。
  4. 静态内部类:JVM 保证安全,懒加载高性能。
  5. 枚举单例:最安全、最简单、官方推荐。

需要我继续整理 线程池、锁、volatile、AQS、JVM 全套并发笔记吗?

相关推荐
yaaakaaang3 小时前
一、单例模式
单例模式
Yupureki7 小时前
《Linux系统编程》20.常见程序设计模式
linux·服务器·c语言·c++·单例模式·建造者模式·责任链模式
pedestrian_h1 天前
Java单例模式回顾
java·单例模式·设计模式
苏渡苇1 天前
枚举的高级用法——用枚举实现策略模式和状态机
java·单例模式·策略模式·枚举·状态机·enum
·心猿意码·3 天前
C++ 线程安全单例模式的底层源码级解析
c++·单例模式
南境十里·墨染春水3 天前
C++传记 详解单例模式(面向对象)
开发语言·c++·单例模式
无籽西瓜a4 天前
【西瓜带你学设计模式 | 第一期-单例模式】单例模式——定义、实现方式、优缺点与适用场景以及注意事项
java·后端·单例模式·设计模式
格图素书5 天前
大数据在电力行业的应用案例解析-【电力技术】(零)大数据在电力行业的典型落地案例(序)
大数据·单例模式
chushiyunen6 天前
python单例模式、大模型一次加载多次复用
开发语言·python·单例模式