单例模式的变种

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 全套并发笔记吗?

相关推荐
重生之我是Java开发战士2 天前
【Java SE】多线程(三):单例模式,阻塞队列,线程池与定时器
java·javascript·单例模式
许彰午3 天前
34_Java设计模式之单例模式
java·单例模式·设计模式
罗超驿5 天前
10.Java单例模式全解析:饿汉式与懒汉式实现及线程安全深度剖析
安全·单例模式·javaee
布朗克1685 天前
33 设计模式精讲
java·单例模式·设计模式
雨浓YN5 天前
基于设计模式的Winform软件框架-01Xml\Log\Ini日志(单例模式+生产者消费者模式)
单例模式·设计模式
仙俊红6 天前
Java 单例模式:类里面为什么可以有自己类型的字段?
java·开发语言·单例模式
swordbob6 天前
prototype 注入到 singleton 里,prototype是否还是线程安全的
安全·spring·单例模式·原型模式
谁似人间西林客8 天前
工业大数据实战:看中国智造如何用数据驱动效率革命
大数据·单例模式
张小姐的猫8 天前
【Linux】多线程 —— 线程池 | 单例模式 | 常见锁
linux·运维·服务器·c++·单例模式·设计模式·策略模式
Java面试题总结9 天前
双重检验锁的单例模式在高并发下的可见性问题
单例模式