Java 单例模式
Java 单例模式
Java 中实现单例模式(Singleton Pattern)主要有以下几种方式,每种方式都有各自的优缺点。下面是对常见实现方式的总结和对比:
🧩 一、饿汉式(Eager Initialization)
public class Singleton {
private static final Singleton instance = new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return instance;
}
}✅ 优点:
- 实现简单。
- 类加载时即创建实例,线程安全。
- 不会出现多线程问题。
❌ 缺点:
- 资源浪费:类加载时就实例化,可能实际不需要用到该实例。
🧊 二、懒汉式(Lazy Initialization,非线程安全)
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}✅ 优点:
- 延迟加载:只有在第一次调用时才创建实例。
❌ 缺点:
- 线程不安全,多线程环境下可能会创建多个实例。
🧵 三、懒汉式(线程安全,加锁)
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}✅ 优点:
- 线程安全。
- 实现简单。
❌ 缺点:
- 性能低:每次调用
getInstance()都要加锁,影响性能。
💡 四、双重检查锁(Double-Checked Locking)
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防止指令重排。
🧘 五、静态内部类(推荐方式)
public class Singleton {
private Singleton() {}
private static class Holder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return Holder.INSTANCE;
}
}✅ 优点:
- 延迟加载。
- 线程安全。
- 性能好,无需同步。
- 实现简单。
❌ 缺点:
- 无明显缺点,属于推荐方式。
🔐 六、枚举实现(最安全、最简单)
public enum Singleton {
INSTANCE;
public void doSomething() {
// ...
}
}✅ 优点:
- 天生线程安全。
- 防止反射和反序列化攻击。
- 简洁优雅。
❌ 缺点:
- 不支持延迟加载。
- 形式上不同于传统类写法,某些场景下不适用(如需要继承)。
📊 对比总结表:
| 实现方式 | 线程安全 | 是否懒加载 | 性能 | 是否推荐 |
|---|---|---|---|---|
| 饿汉式 | ✅ | ❌ | 高 | ❌ |
| 懒汉式(非线程) | ❌ | ✅ | 高 | ❌ |
| 懒汉式(同步方法) | ✅ | ✅ | 低 | ❌ |
| 双重检查锁 | ✅ | ✅ | 高 | ✅ |
| 静态内部类 | ✅ | ✅ | 高 | ✅✅✅ |
| 枚举实现 | ✅ | ❌ | 高 | ✅✅✅ |
✅ 推荐使用:
- 如果可以不使用延迟加载 ➤ 枚举方式(最安全)
- 如果需要延迟加载 ➤ 静态内部类方式
Java 单例模式
https://liuyuhe666.github.io/2025/07/12/Java-单例模式/