Java单例模式实现:七种写法解析
需积分: 15 76 浏览量
更新于2024-09-07
收藏 177KB PDF 举报
"单例模式是设计模式中的一种,它的核心思想是确保一个类只有一个实例,并提供一个全局访问点。在Java中,实现单例模式有多种方式,每种方式都有其特点和适用场景。以下是对单例模式七种写法的详细解释:
1. **懒汉式(线程不安全)**:
这是最简单的实现,只有在第一次调用`getInstance()`方法时才会创建实例。但这种方式在多线程环境下存在竞态条件,可能导致多个线程各自创建一个实例,不符合单例模式的要求。
2. **懒汉式(线程安全)**:
通过在`getInstance()`方法上添加`synchronized`关键字,解决了线程安全问题,确保同一时刻只有一个线程可以执行创建实例的代码。但这样会降低性能,因为每次调用`getInstance()`都需要进行同步,即使实例已经创建完成。
3. **饿汉式**:
在类加载时就创建了单例实例,因此是线程安全的。但这种方式不满足懒加载,即无论何时何地,只要类被加载就会创建实例,可能导致不必要的内存消耗。
4. **饿汉式(变种)**:
使用`static final`字段存储实例,这种方式同样在类加载时创建实例,且由于`final`修饰,无法被改变,确保了线程安全。与第三种方式相比,这种方式更接近于常量,但依然不支持懒加载。
5. **双检锁/双重检查锁定(DCL,Double-Check Locking)**:
Java代码:
```
public class Singleton {
private volatile static Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
```
这种方式结合了前两种方法的优点,既实现了懒加载,又保证了线程安全。在`instance`未创建之前,线程进入同步块,确保了实例创建过程中不会被其他线程干扰。`volatile`关键字保证了多线程环境下`instance`变量的可见性,避免了指令重排序的问题。
6. **静态内部类**:
```
public class Singleton {
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
private Singleton() {}
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
```
这种方式利用了Java类加载机制,保证了线程安全且实现了延迟加载。静态内部类只有在被首次引用时才会加载,因此`INSTANCE`实例的创建也是延迟的。
7. **枚举**:
```
public enum Singleton {
INSTANCE;
public void whateverMethod() {
}
}
```
通过枚举方式实现单例,既简单又安全,还能防止反射和序列化攻击。这是推荐的最佳实践,因为它既满足了单例的所有需求,又具有良好的编码习惯。
以上七种方式在不同的场景下各有优势,选择哪种方式取决于具体的需求,如是否需要懒加载、对性能的要求、以及是否考虑反序列化或反射攻击等因素。在实际开发中,通常会选择DCL或者枚举方式,因为他们既保证了线程安全,又能实现延迟加载,同时也避免了反射和序列化的问题。
2020-11-29 上传
2018-11-29 上传
点击了解资源详情
2018-07-13 上传
2022-08-08 上传
2020-12-22 上传
2020-09-19 上传
weixin_38669628
- 粉丝: 387
- 资源: 6万+
最新资源
- Raspberry Pi OpenCL驱动程序安装与QEMU仿真指南
- Apache RocketMQ Go客户端:全面支持与消息处理功能
- WStage平台:无线传感器网络阶段数据交互技术
- 基于Java SpringBoot和微信小程序的ssm智能仓储系统开发
- CorrectMe项目:自动更正与建议API的开发与应用
- IdeaBiz请求处理程序JAVA:自动化API调用与令牌管理
- 墨西哥面包店研讨会:介绍关键业绩指标(KPI)与评估标准
- 2014年Android音乐播放器源码学习分享
- CleverRecyclerView扩展库:滑动效果与特性增强
- 利用Python和SURF特征识别斑点猫图像
- Wurpr开源PHP MySQL包装器:安全易用且高效
- Scratch少儿编程:Kanon妹系闹钟音效素材包
- 食品分享社交应用的开发教程与功能介绍
- Cookies by lfj.io: 浏览数据智能管理与同步工具
- 掌握SSH框架与SpringMVC Hibernate集成教程
- C语言实现FFT算法及互相关性能优化指南