java单例实现有五种方式:懒汉式(双重检查+volatile)、饿汉式(类加载即初始化)、静态内部类(延迟加载+jvm线程安全)、枚举式(防反射/反序列化破坏)及必须私有构造方法。

Java 中实现单例类,核心是控制实例的创建次数为 1,并确保全局访问点始终返回同一个对象。关键在于:私有构造方法 + 静态私有实例 + 公共静态获取方法。
懒汉式(线程安全版)
在第一次调用 getInstance() 时才创建实例,节省资源;但多线程下需加锁避免重复初始化。
public class Singleton {
private static volatile Singleton instance;
private Singleton() {} // 私有构造,禁止外部 new
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
- volatile 防止指令重排序,保证其他线程能看到完全初始化的对象
- 双重检查锁定(Double-Check Locking)兼顾性能与线程安全
饿汉式(最简单可靠)
类加载时就创建实例,天然线程安全,但可能造成资源浪费(如果实例一直不被使用)。
public class Singleton {
private static final Singleton instance = new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return instance;
}
}
- 利用类加载机制保证单例,无需同步,无并发问题
- 适合实例创建开销小、且一定会用到的场景
静态内部类(推荐)
结合懒加载和线程安全,利用 JVM 类加载机制延迟初始化,写法简洁且高效。
public class Singleton {
private Singleton() {}
private static class Holder {
static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return Holder.INSTANCE;
}
}
- Holder 类在首次调用 getInstance() 时才被加载,触发实例创建
- JVM 保证类加载过程线程安全,无需手动同步
- 没有 volatile 和 synchronized,性能好,代码清晰
枚举方式(最防破坏)
不仅能防止多线程问题,还能天然抵抗反序列化、反射攻击等单例被破坏的情况。
public enum Singleton {
INSTANCE;
public void doSomething() {
// 业务方法
}
}
- 调用 Singleton.INSTANCE 即可获取唯一实例
- JVM 保证枚举实例全局唯一且线程安全
- 无法通过反射或反序列化生成新实例(强烈推荐用于高安全性要求场景)
不复杂但容易忽略:无论哪种方式,都要确保构造方法私有,否则外部仍可通过 new 破坏单例约束。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











