当前位置: 首页 > java >正文

单例模式 (Singleton Pattern)

单例模式是一种创建型设计模式,它确保一个类只有一个实例,并提供一个全局访问点来访问该实例。

核心特点

  1. 唯一性:一个类只能有一个实例

  2. 全局访问:提供全局访问该实例的方式

  3. 延迟初始化:通常在第一次被请求时才创建实例(可选)

实现方式(Java示例)

1. 饿汉式(线程安全,类加载时初始化)

public class Singleton {// 类加载时就创建实例private static final Singleton instance = new Singleton();// 私有构造函数,防止外部实例化private Singleton() {}// 全局访问点public static Singleton getInstance() {return instance;}
}

优点:实现简单,线程安全
缺点:如果实例未被使用,会造成资源浪费

2. 懒汉式(非线程安全)

public class Singleton {private static Singleton instance;private Singleton() {}public static Singleton getInstance() {if (instance == null) {instance = new Singleton();}return instance;}
}

缺点:多线程环境下可能创建多个实例

3. 线程安全的懒汉式(同步方法)

public class Singleton {private static Singleton instance;private Singleton() {}public static synchronized Singleton getInstance() {if (instance == null) {instance = new Singleton();}return instance;}
}

优点:线程安全
缺点:每次获取实例都要同步,性能较差

4. 双重检查锁定(DCL,推荐方式)

public class Singleton {// volatile保证可见性和禁止指令重排序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;}
}

优点:线程安全,性能较好(只有第一次创建时需要同步)

5. 静态内部类实现(推荐方式)

public class Singleton {private Singleton() {}private static class Holder {private static final Singleton INSTANCE = new Singleton();}public static Singleton getInstance() {return Holder.INSTANCE;}
}

优点:线程安全,延迟加载,实现简单

6. 枚举实现(最佳方式,Java 1.5+)

public enum Singleton {INSTANCE;public void doSomething() {// 业务方法}
}

优点:线程安全,防止反射攻击,防止反序列化重新创建对象
缺点:不够灵活(不能延迟初始化)

应用场景

  1. 配置管理:全局配置对象

  2. 日志记录器:应用只需要一个日志记录器实例

  3. 数据库连接池:避免频繁创建和销毁连接

  4. 线程池:管理应用中的线程资源

  5. 缓存系统:全局缓存访问点

注意事项

  1. 多线程环境:确保线程安全

  2. 序列化:如果需要序列化,应实现readResolve()方法防止反序列化创建新实例

  3. 反射攻击:可以通过反射调用私有构造函数,需要额外防护

  4. 单元测试:单例可能使测试变得困难(难以模拟替代)

  5. 全局状态:过度使用单例可能导致代码耦合度高

单例模式是设计模式中最简单但也是最容易误用的模式之一,应谨慎使用,避免滥用。

http://www.xdnf.cn/news/926.html

相关文章:

  • DeepSeek R1模型微调怎么做?从入门到实战
  • 关于敏感文件或备份 安全配置错误 禁止通过 URL 访问 Vue 项目打包后的 .gz 压缩文件
  • RS232转Profibus DP网关:技术革新!
  • 【Pandas】pandas DataFrame sub
  • Discuz!与DeepSeek的深度融合:打造智能网址导航新标杆
  • 在Ubuntu 18.04下编译OpenJDK 11
  • BEVDet4D: Exploit Temporal Cues in Multi-camera 3D Object Detection
  • 树模型与集成学习(决策树核心算法:ID3/C4.5/CART、随机森林、GBDT/XGBoost)
  • CentOS7系统安装Docker教程
  • 【NLP 67、知识图谱】
  • 开源脚本分享:用matlab处理ltspice生成的.raw双脉冲数据
  • JDBC:数据库访问的原始接口
  • 【数据结构和算法】3. 排序算法
  • ubuntu20.04安装安装x11vnc服务基于gdm3或lightdm这两种主流的显示管理器。
  • LlamaIndex 生成的本地索引文件和文件夹详解
  • PaginationInnerInterceptor使用(Mybatis-plus分页)
  • RUI 桌面 appTV 版中文版下载 RUI 桌面桌面固件包实用攻略
  • Visual Studio 2022 运行一个后台程序而不显示控制台窗口
  • 悟空黑桃 下载地址
  • 自动驾驶最新算法进展
  • 【EasyPan】项目常见问题解答(自用持续更新中…)
  • 位运算题目:循环码排列
  • Lesson 7 DNS域名解析服务器
  • Java秒杀功能-案例
  • jvm-获取方法签名的方法
  • 【uniapp-兼容性处理】安卓uView组件中u-input后置插槽不展示
  • 03-HTML常见元素
  • win10设置软件开机自启
  • 从0开始配置spark-local模式
  • 聊透多线程编程-线程互斥与同步-12. C# Monitor类实现线程互斥