几种单例的比较
目次
懒汉式 #
|
|
|
|
优势:
- 实现简单;
- 没有同步开销;
不足:
- 类加载时创建,可能造成资源浪费;
线程安全:
JVM保障(静态变量只在加载时创建一次)。
饿汉式 #
|
|
|
|
优势:
- 减少了不必要的资源浪费
不足:
- 首次访问有同步开销
线程安全:
需要依赖同步锁实现线程安全。
双重检查式 #
|
|
|
|
优势:
- 延迟加载
- 只有第一次访问时有同步开销
不足:
- 实现复杂
线程安全:
volatile防止指令重排序。
静态内部类 #
|
|
|
|
优势:
- 实现简单
- 没有同步开销
不足:
- 无法初始化参数
线程安全:
JVM保障,同饿汉式。
枚举单例 #
|
|
优势:
- 方式反射、序列化破坏单例;
不足:
- 可嫩造成不必要的资源浪费;
线程安全:
由JVM保证(类似静态单例初始化)。
总结 #
类型 | 实现方式 | 语言 | 线程安全 | 初始化时机 | 优势 | 不足 | 线程安全保证机制 |
---|---|---|---|---|---|---|---|
非懒加载 | 饿汉式 | Java | ✅ | 类加载时 | 实现简单,无同步开销 | 可能造成资源浪费 | JVM类加载机制 |
枚举单例 | Java | ✅ | 类加载时 | 绝对防止反射/序列化破坏 | 不够灵活 | JVM枚举特性保证 | |
Object声明 | Kotlin | ✅ | 首次访问类时 | 语法级支持,简洁安全 | 非严格懒加载 | 编译器生成静态内部类 | |
懒加载 | 同步方法 | Java | ✅ | 首次调用时 | 延迟加载节省资源 | 每次调用都同步,性能差 | synchronized方法锁 |
双重检查锁(DCL) | Java | ✅ | 首次调用时 | 高性能(仅首次同步) | 实现复杂,需volatile | volatile+同步块禁止指令重排 | |
静态内部类 | Java | ✅ | 首次调用时 | 无同步开销,优雅实现 | 无法传递初始化参数 | JVM类加载机制 | |
lazy(SYNCHRONIZED) | Kotlin | ✅ | 首次属性访问时 | 灵活控制初始化时机 | 首次访问有同步开销 | 委托内部使用同步锁 | |
lazy(PUBLICATION) | Kotlin | ⚠️有条件 | 首次属性访问时 | 允许多线程并行初始化 | 可能多次初始化 | CAS操作保证最终一致性 | |
lazy(NONE) | Kotlin | ❌ | 首次属性访问时 | 完全无同步开销 | 仅限单线程环境 | 无保护机制 |
Categories: