Java单例模式总结
说明:单例模式的核心是确保一个类只有一个实例,并提供全局访问点。饿汉式和懒汉式是两种常见的实现方式
一、饿汉式和懒汉式
1. 饿汉式(Eager Initialization)
public class EagerSingleton {// 类加载时直接初始化实例private static final EagerSingleton instance = new EagerSingleton();// 私有构造方法,防止外部 new 实例private EagerSingleton() {}// 提供全局访问点public static EagerSingleton getInstance() {return instance;}
}
优点:
- 线程安全:实例在类加载时创建,JVM 保证初始化过程的线程安全。
- 实现简单:无需处理同步逻辑。
缺点:
- 资源浪费:即使未使用,实例也会在程序启动时被创建。
- 无法延迟加载:不适合初始化耗资源的场景。
2.懒汉式(Lazy Initialization)
代码实现(基础版,非线程安全):
public class LazySingleton {private static LazySingleton instance;private LazySingleton() {}// 非线程安全!public static LazySingleton getInstance() {if (instance == null) {instance = new LazySingleton();}return instance;}
}
代码改进(双重检查锁定,线程安全):
public class ThreadSafeSingleton {private static volatile ThreadSafeSingleton instance; // volatile 禁止指令重排private ThreadSafeSingleton() {}public static ThreadSafeSingleton getInstance() {if (instance == null) { // 第一次检查synchronized (ThreadSafeSingleton.class) { // 加锁if (instance == null) { // 第二次检查instance = new ThreadSafeSingleton();}}}return instance;}
}
优点:
- 延迟加载:实例在第一次使用时创建,节省资源。
- 线程安全(双重检查版):通过同步块和 volatile 确保线程安全。
缺点:
- 实现复杂:需处理双重检查锁定和 volatile 关键字。
- 性能开销:同步锁可能影响高并发场景的性能(双重检查已优化)。
二、当前流行的单利模式
Kotlin 通过语言特性简化了单例模式的实现,提供两种主流方式:
1. 使用 object 关键字(饿汉式)
object Singleton {fun doSomething() {println("Kotlin object singleton")}
}// 调用方式
Singleton.doSomething()
特点:
- 线程安全:由 JVM 保证初始化线程安全。
- 饿汉式:实例在类加载时创建。
- 代码极简:无需手动编写单例逻辑。
2. 使用 lazy 函数(懒汉式)
class LazySingleton private constructor() {companion object {val instance: LazySingleton by lazy {LazySingleton()}}fun doSomething() {println("Kotlin lazy singleton")}
}// 调用方式
LazySingleton.instance.doSomething()
特点:
- 线程安全:lazy 默认使用 LazyThreadSafetyMode.SYNCHRONIZED 保证线程安全。
- 延迟加载:实例在首次访问时创建。
- 灵活性:可自定义初始化逻辑(如传递参数)。
推荐实践:
- 在 Kotlin 中优先使用 object 或 lazy,避免手动实现单例逻辑。
- 需要延迟加载时选择 lazy,否则直接使用 object。