一、单例模式是什么单例模式Singleton是创建型设计模式。核心定义保证一个类在整个程序运行中有且仅有一个实例对象并提供一个全局访问入口。二、单例模式三大核心特点必背私有构造方法禁止外部 new 对象私有静态实例类内部唯一对象公共静态方法全局唯一获取实例入口三、单例解决什么问题避免重复创建对象节省内存全局统一资源管控连接池、配置类、工具类保证操作唯一性日志、计数器、线程池四、两大分类饿汉式类加载时直接创建实例 →无懒加载、线程安全懒汉式使用时才创建实例 →懒加载、省内存、需要解决线程安全五、八种实现方式1. 饿汉式静态常量【可用、简单】特点类加载直接初始化天生线程安全javapublic class Singleton { // 1. 静态常量实例 private static final Singleton instance new Singleton(); // 2. 私有构造 private Singleton(){} // 3. 全局获取 public static Singleton getInstance(){ return instance; } }✅ 优点简单、无锁、线程绝对安全、性能高 ❌ 缺点无懒加载类加载就创建不用也占内存2. 饿汉式静态代码块适合需要初始化额外资源javapublic class Singleton { private static Singleton instance; static { instance new Singleton(); } private Singleton(){} public static Singleton getInstance(){ return instance; } }3. 懒汉式线程不安全特点用时才创建多线程会创建多个实例javapublic class Singleton { private static Singleton instance; private Singleton(){} public static Singleton getInstance(){ if(instance null){ instance new Singleton(); } return instance; } }❌ 致命问题多线程并发会创建多个对象4. 懒汉式同步方法javapublic class Singleton { private static Singleton instance; private Singleton(){} // 加锁 public static synchronized Singleton getInstance(){ if(instance null){ instance new Singleton(); } return instance; } }✅ 线程安全 ❌每次获取都加锁高并发性能极差5. 懒汉式同步代码块java// 错误不能保证单例 public static Singleton getInstance(){ if(instance null){ synchronized (Singleton.class){ instance new Singleton(); } } return instance; }❌双重检查缺失第一层锁判断多线程依旧会重复创建6. 双重检查锁 DCL终极优化懒加载 线程安全 高性能javapublic class Singleton { // volatile 禁止指令重排核心 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面试必考new 对象底层三步开辟内存空间初始化对象赋值给 instanceCPU 指令重排可能变成1→3→2 导致其他线程拿到半初始化对象程序报错。volatile 作用禁止指令重排、保证可见性✅ 优点懒加载、线程安全、并发高性能 ❌ 写法稍复杂、需要理解 volatile7. 静态内部类单例javapublic class Singleton { // 私有构造 private Singleton(){} // 静态内部类外部类加载不会加载内部类 private static class Inner{ private static final Singleton INSTANCE new Singleton(); } public static Singleton getInstance(){ return Inner.INSTANCE; } }原理满分解释外部类加载不加载内部类→ 实现懒加载内部类静态变量初始化由 JVM 保证线程安全调用getInstance()才加载内部类创建唯一实例✅ 懒加载 ✅ 无锁、性能极高 ✅ JVM 天然线程安全 面试最推荐、代码简洁、无坑❌ 缺点无法防止反射破坏单例8. 枚举单例javapublic enum Singleton { INSTANCE; // 自定义方法 public void doSomething(){ System.out.println(业务方法); } }使用javaSingleton.INSTANCE.doSomething();最强优点绝对线程安全杜绝反射破坏、序列化破坏写法极简天然单例、不会多创建✅Java 官方公认最完美单例❌ 不支持懒加载类加载直接初始化六、四大破坏单例的方式 防护1. 反射破坏通过暴力反射创建新对象除了枚举全部可破。枚举天然防反射2. 序列化破坏对象序列化再反序列化会生成新对象。 枚举天然防序列化。3. 克隆破坏重写 clone 方法会产生新对象。4. 多线程并发普通懒汉式无锁直接失效。七、八种单例终极对比表背诵版表格方式懒加载线程安全性能防反射推荐度饿汉静态常量❌✅极高❌⭐⭐⭐饿汉静态代码块❌✅极高❌⭐⭐⭐普通懒汉✅❌高❌❌废弃同步方法懒汉✅✅极低❌⭐⭐同步代码块懒汉✅❌高❌❌错误DCL 双重检查✅✅极高❌⭐⭐⭐⭐静态内部类✅✅极高❌⭐⭐⭐⭐⭐枚举❌✅极高✅⭐⭐⭐⭐⭐⭐八、开发中到底用哪个需要懒加载、高性能、无漏洞 → 静态内部类高并发、框架底层、绝对安全 → 枚举简单工具类、无需懒加载 → 饿汉式面试手写最优代码 → DCL / 静态内部类九、单例模式真实业务场景Spring Bean 默认单例数据库连接池Redis 连接工具类全局配置类、系统参数日志工具、计数器线程池对象系统缓存管理器十、面试高频问答1. DCL 为什么要 volatile防止 JVM 指令重排避免线程获取半初始化对象保证多线程安全。2. 静态内部类原理利用外部类不加载内部类实现懒加载利用JVM 静态初始化线程安全保证单例。3. 枚举为什么是最完美单例JVM 底层禁止反射枚举构造方法天然杜绝反射、序列化、多线程问题。4. 饿汉和懒汉区别饿汉类加载创建无懒加载、省锁、费内存 懒汉用时创建懒加载、省内存、需要控线程安全