
单例模式实现 线程安全面试markdown版单例保证一个类在整个应用中只有一个实例对象提供全局访问点。1. 饿汉式静态常量publicclassSingleton{// 类加载直接初始化实例privatestaticfinalSingletonINSTANCEnewSingleton();privateSingleton(){}publicstaticSingletongetInstance(){returnINSTANCE;}}线程安全✅ 类加载阶段就创建实例JVM类加载机制保证线程安全缺点类加载就创建对象不管用不用会占用内存不支持懒加载2. 懒汉式非线程安全不推荐publicclassSingleton{privatestaticSingletoninstance;privateSingleton(){}publicstaticSingletongetInstance(){if(instancenull){instancenewSingleton();}returninstance;}}线程安全❌ 多线程并发会创建多个实例优点懒加载用到才创建缺点并发场景直接报废3. 懒汉式 synchronized 方法加锁性能差publicstaticsynchronizedSingletongetInstance(){if(instancenull){instancenewSingleton();}returninstance;}线程安全✅缺点每次调用getInstance都要获取锁高并发性能很低4. 双重检查锁 DCLDouble‑Checked Lock生产常用publicclassSingleton{// 必须加volatile防止指令重排privatestaticvolatileSingletoninstance;privateSingleton(){}publicstaticSingletongetInstance(){// 第一次判断不为空直接返回减少锁竞争if(instancenull){synchronized(Singleton.class){// 第二次判断防止多个线程等待锁后重复创建if(instancenull){instancenewSingleton();}}}returninstance;}}线程安全✅volatile作用禁止new Singleton()指令重排。new对象分三步分配内存→初始化对象→赋值引用不加volatile可能先赋值再初始化其他线程拿到半初始化对象。优点懒加载、并发性能好5. 静态内部类推荐最优publicclassSingleton{privateSingleton(){}// 静态内部类只有调用getInstance才会加载privatestaticclassSingletonHolder{privatestaticfinalSingletonINSTANCEnewSingleton();}publicstaticSingletongetInstance(){returnSingletonHolder.INSTANCE;}}线程安全✅ JVM类加载保证没有锁开销原理外部类加载不会加载内部类只有访问SingletonHolder才初始化实例优点懒加载、无线锁、实现简洁6. 枚举单例Effective Java推荐防反射、防序列化破坏publicenumSingletonEnum{INSTANCE;//业务方法publicvoiddoSomething(){}}线程安全✅优势天然防止反射、序列化破坏单例写法最简单缺点饿汉类加载就实例化不支持懒加载如何保证单例线程安全总结饿汉式 / 静态内部类 / 枚举依靠JVM类加载机制保证线程安全不需要手动加锁。懒汉同步方法依靠synchronized方法锁性能差。DCL双重检查锁synchronizedvolatile既要锁又要禁止指令重排。注意点反射可以暴力调用私有构造器破坏单例枚举天然规避这个问题。序列化/反序列化也会破坏普通单例枚举同样天然解决。总结追求简单安全枚举想要懒加载、高性能静态内部类需要手动控制实例创建时机DCL双重检查锁