static是实现单例的核心,饿汉式利用static字段类加载时初始化,天然线程安全但可能资源浪费;懒汉式通过static方法延迟创建,需volatile+synchronized保证线程安全;枚举式依托jvm静态初始化,兼具线程安全、防反射与简洁性。

Java 中 static 是实现单例模式的关键,它让类变量和方法脱离实例存在,确保全局唯一性。懒汉式靠 static 延迟初始化,饿汉式靠 static 在类加载时就完成实例创建。
饿汉式:static 变量直接初始化
利用 static 字段在类加载阶段就被初始化的特性,天然线程安全,但可能造成资源浪费(实例未被使用时已创建)。
示例:
public class EagerSingleton {
private static final EagerSingleton instance = new EagerSingleton();
private EagerSingleton() {} // 私有构造防止外部 new
public static EagerSingleton getInstance() {
return instance;
}
}
- instance 是 static + final:保证唯一、不可变、类加载即存在
- 无同步开销,调用
getInstance()直接返回引用 - 如果该单例依赖重量级资源(如数据库连接),而程序始终不调用
getInstance(),则提前创建是低效的
懒汉式:static 方法中按需创建
把实例创建推迟到第一次调用 getInstance() 时,节省资源;但多线程下需处理竞态条件,static 方法本身不保证线程安全,必须额外加锁或使用双重检查锁定(DCL)。
基础版(线程不安全):
public class LazySingleton {
private static LazySingleton instance;
private LazySingleton() {}
public static LazySingleton getInstance() {
if (instance == null) {
instance = new LazySingleton(); // 多线程下可能重复创建
}
return instance;
}
}
推荐版(双重检查锁定 + volatile):
public class LazySingleton {
private static volatile LazySingleton instance; // volatile 防止指令重排序
private LazySingleton() {}
public static LazySingleton getInstance() {
if (instance == null) {
synchronized (LazySingleton.class) {
if (instance == null) {
instance = new LazySingleton();
}
}
}
return instance;
}
}
-
volatile 关键:禁止 JVM 对
new LazySingleton()的初始化步骤重排序,避免其他线程拿到未构造完成的对象 - 外层 null 检查减少同步开销,仅首次创建时加锁
- 静态方法
getInstance()是入口,所有访问都通过它,配合static字段实现“单例”语义
static 在单例中的核心作用
-
类级别共享:static 字段属于类而非对象,所有线程看到的是同一个
instance - 生命周期匹配:static 变量随类加载而存在,随类卸载而销毁,与单例“全局唯一、长期存活”的需求一致
- 访问便捷性:static 方法无需实例即可调用,自然适合作为单例获取入口
补充:枚举实现(更简洁安全)
Java 枚举天生单例、线程安全、防反射/反序列化攻击,本质也依赖 JVM 对枚举类的 static 初始化机制:
public enum SingletonEnum {
INSTANCE;
public void doSomething() {
// 业务方法
}
}
- 调用:
SingletonEnum.INSTANCE.doSomething() - JVM 保证枚举常量在类加载时初始化且仅一次
- 比手写懒汉/饿汉更少出错,适合大多数场景
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











