Java 单例模式(Singleton Pattern)详解
🌟 什么是单例模式?
单例模式确保一个类只有一个实例,并提供一个全局访问点来访问它。
🧠 使用场景
- 配置管理类(如读取配置文件)
- 日志工具类(如 Log4j 的 Logger)
- 数据库连接池
- 缓存管理
- 线程池
✅ 实现方式(Java)
方式一:饿汉式(类加载时就实例化)
java
public class Singleton {
private static final Singleton instance = new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return instance;
}
}
- 优点:简单、线程安全
- 缺点:类加载时就创建实例,可能浪费资源
方式二:懒汉式(线程不安全)
java
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
- 缺点:多线程环境会创建多个实例
方式三:懒汉式 + synchronized(线程安全)
java
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
- 缺点:加锁影响性能
方式四:双重检查锁(DCL)
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
public class Singleton {
private Singleton() {}
private static class Holder {
private static final Singleton instance = new Singleton();
}
public static Singleton getInstance() {
return Holder.instance;
}
}
- 优点:利用 JVM 机制,线程安全 + 懒加载 + 高性能
方式六:枚举实现(最推荐)
java
public enum Singleton {
INSTANCE;
public void doSomething() {
System.out.println("Doing something...");
}
}
- 优点:防反射、防反序列化、天然线程安全
- 缺点:不能延迟加载
🔐 防止反射与反序列化破坏单例
防反射
java
private Singleton() {
if (instance != null) {
throw new RuntimeException("反射破坏单例!");
}
}
防反序列化
java
private Object readResolve() {
return instance;
}
📌 各方式对比
实现方式 | 是否懒加载 | 是否线程安全 | 推荐度 |
---|---|---|---|
饿汉式 | 否 | 是 | ★★ |
懒汉式 | 是 | 否 | ★ |
synchronized | 是 | 是 | ★★ |
DCL | 是 | 是 | ★★★★ |
静态内部类 | 是 | 是 | ★★★★★ |
枚举 | 否 | 是 | ★★★★★(最安全) |