懒汉式单例在Java中实现延迟加载,常用双重检查锁定(需volatile)和静态内部类两种线程安全方式,后者因无同步开销、天然安全且简洁而更推荐。

懒汉式单例在 Java 中指类的实例在第一次被使用时才创建,实现延迟加载,节省资源。但需特别注意线程安全问题,否则多线程环境下可能生成多个实例。
基础懒汉式(非线程安全)
仅适合单线程场景,不推荐用于实际项目:
public class LazySingleton {
private static LazySingleton instance;
private LazySingleton() {} // 私有构造防止外部 new
public static LazySingleton getInstance() {
if (instance == null) {
instance = new LazySingleton(); // 多线程下可能重复执行
}
return instance;
}
}
问题:若两个线程同时判断 instance == null 为 true,都进入 if 块,就会创建两个对象。
同步方法版(线程安全但性能差)
用 synchronized 修饰整个 getInstance() 方法,保证同一时刻只有一个线程能进入:
立即学习“Java免费学习笔记(深入)”;
public static synchronized LazySingleton getInstance() {
if (instance == null) {
instance = new LazySingleton();
}
return instance;
}
缺点:每次调用都要加锁,即使实例已存在,影响并发性能。
双重检查锁定(推荐的懒汉式)
兼顾线程安全与性能,是常用实现方式。关键点:
- 外层 if 避免已初始化后重复加锁
- 内层 if 在加锁后再次校验,防止多个线程在等待锁释放后重复创建
-
必须用
volatile修饰 instance,禁止指令重排序,确保其他线程能看到完全初始化的对象
public class LazySingleton {
private static volatile LazySingleton instance;
private LazySingleton() {}
public static LazySingleton getInstance() {
if (instance == null) { // 第一次检查
synchronized (LazySingleton.class) {
if (instance == null) { // 第二次检查
instance = new LazySingleton(); // volatile 保证可见性与有序性
}
}
}
return instance;
}
}
静态内部类方式(更优雅的懒汉式)
利用 JVM 类加载机制保证线程安全和延迟加载,无需 synchronized 或 volatile:
public class LazySingleton {
private LazySingleton() {}
private static class Holder {
private static final LazySingleton INSTANCE = new LazySingleton();
}
public static LazySingleton getInstance() {
return Holder.INSTANCE; // Holder 类首次被访问时才加载并初始化 INSTANCE
}
}
优势:写法简洁、天然线程安全、延迟加载、无同步开销。是多数场景下的首选懒汉式实现。


















