Java单例模式有五种可靠实现:饿汉式(类加载即初始化,线程安全但可能浪费资源)、懒汉式+双重检查锁(延迟加载、volatile+synchronized保障线程安全)、静态内部类(利用类加载机制实现优雅懒加载)、枚举式(天然防反射和反序列化,最安全)、以及需注意私有构造等细节避免失效。

Java 中实现单例模式,核心是控制类的实例化过程,确保整个 JVM 进程中该类有且仅有一个实例。关键点有三个:私有构造方法、静态私有实例、全局访问的静态获取方法。下面介绍几种常用且可靠的实现方式。
饿汉式(线程安全,简单直接)
在类加载时就创建好唯一实例,天然线程安全,但可能造成资源浪费(如果实例一直不被使用)。
示例代码:
public class Singleton {
private static final Singleton instance = new Singleton();
private Singleton() {} // 私有构造,禁止外部 new
public static Singleton getInstance() {
return instance;
}
}
- 类加载即初始化,无需同步,性能高
- 适合实例创建开销小、且必然会被使用的场景
懒汉式 + 双重检查锁(推荐,兼顾延迟加载与线程安全)
第一次调用 getInstance() 时才创建实例,通过 volatile 和 synchronized 防止指令重排序和多线程竞争问题。
立即学习“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 关键字防止对象未完全构造就被其他线程读取
- 双重检查减少同步开销,适合高并发、低频初始化场景
静态内部类(最优雅的懒加载方案)
利用 Java 类加载机制:外部类加载时,内部类不会被加载;只有调用 getInstance() 触发内部类加载,才初始化实例。JVM 保证类初始化线程安全。
示例代码:
public class Singleton {
private Singleton() {}
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
- 无同步、无 volatile,写法简洁,线程安全,延迟加载
- 被广泛认为是最佳实践之一
枚举方式(防反射、防序列化,最安全)
借助 Java 枚举的天然单例特性,还能天然防止反射攻击和反序列化破坏单例。
示例代码:
public enum Singleton {
INSTANCE;
public void doSomething() {
// 业务方法
}
}
- 获取实例:Singleton.INSTANCE
- 即使通过反射也无法创建新实例,反序列化也返回同一实例
- 适合对安全性要求极高的场景(如配置管理、连接池核心控制器)
选择哪种方式取决于具体需求:追求简洁安全选枚举;强调延迟加载又不想写同步逻辑,选静态内部类;需要兼容老版本或明确控制初始化时机,可用双重检查锁。不复杂但容易忽略细节,比如 volatile 缺失或构造器未私有化,都会导致单例失效。


















