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

【单例模式】简介

目录

  • 概念理解
  • 使用场景
  • 优缺点
  • 实现方式

概念理解

单例模式要保证一个类在整个系统运行期间,无论创建多少次该类的对象,始终只会有一个实例存在。就像操作系统中的任务管理器,无论何时何地调用它,都是同一个任务管理器在工作,不会同时出现多个不同的任务管理器实例

使用场景

  • 资源共享:当多个模块需要共享同一个资源时,使用单例模式可以避免资源的重复创建和浪费。例如,数据库连接池,使用单例模式可以确保所有模块使用的同一个数据库连接池,避免了 多个连接池的创建,提高了资源的利用率
  • 日志记录器:在一个应用程序中,通常只需要一个日志记录器来记录系统的运行信息。使用单例模式可以确保所有模块都使用同一个日志记录器,避免了日志信息的分散和混乱
  • 配置管理:在一个系统中,配置信息通常是全局的,并且只需要一份。使用单例模式中可以确保所有模块都使用同一个配置对象,方便对配置信息进行统一管理和修改

优缺点

优点

  • 节省资源:由于只创建一个实例,减少了系统资源的开销,特别是对于一些创建和销毁开销较大的对象,如数据库连接、文件系统等。
  • 全局访问:提供了一个全局访问点,方便其他模块获取该实例,避免了在多个地方重复创建对象。
  • 数据一致性:由于所有模块都使用同一个实例,保证了数据的一致性和完整性。
    缺点
  • 违反单一职责原则:单例模式的类既负责创建实例,又负责管理实例的生命周期,违反了单一职责原则。
  • 扩展性差:由于单例模式的类只有一个实例,难以进行扩展和修改。如果需要对单例类进行扩展,可能需要修改原有的代码,不符合开闭原则。
  • 多线程问题:在多线程环境下,如果没有进行适当的同步处理,可能会导致多个线程同时创建实例,破坏单例模式的唯一性。

实现方式

懒汉式(线程不安全)

class Singleton:_instance = None@classmethoddef get_instance(cls):if cls._instance is None:cls._instance = cls()return cls._instance# 使用示例
s1 = Singleton.get_instance()
s2 = Singleton.get_instance()
print(s1 is s2)  # 输出: True

这种方式在第一次调用 get_instance 方法时才创建实例,但在多线程环境下可能会创建多个实例。
懒汉式(线程安全)

import threadingclass Singleton:_instance = None_lock = threading.Lock()@classmethoddef get_instance(cls):with cls._lock:if cls._instance is None:cls._instance = cls()return cls._instance# 使用示例
s1 = Singleton.get_instance()
s2 = Singleton.get_instance()
print(s1 is s2)  # 输出: True

通过加锁的方式保证在多线程环境下也只会创建一个实例,但每次获取实例都需要加锁,会影响性能。

饿汉式

class Singleton:_instance = Nonedef __new__(cls, *args, **kwargs):if not cls._instance:cls._instance = super().__new__(cls, *args, **kwargs)return cls._instance# 使用示例
s1 = Singleton()
s2 = Singleton()
print(s1 is s2)  # 输出: True

这种方式在类加载时就创建实例,避免了多线程问题,但如果实例创建过程比较耗时,会影响系统的启动性能。

相关文章:

  • 服务器频繁重启日志分析与诊断
  • AttributeError: module ‘distutils‘ has no attribute ‘version‘
  • Unity URPShader:实现和PS一样的色相/饱和度调整参数效果(修复)
  • windows 使用websocket++ (C++环境)
  • 探索MySQL InnoDB:事务、日志与锁的奥秘
  • Redis应用场景实战:穿透/雪崩/击穿解决方案与分布式锁深度剖析
  • PostgreSQL可串行化快照隔离和冻结处理
  • Kaamel白皮书:MCP安全实践
  • 论软件系统的透明性挑战及应对策略
  • ArcGIS+GPT:多领域地理分析与决策新方案
  • 产品月报|睿本云4月产品功能迭代
  • JAVA学习-练习试用Java实现“实现一个生成对抗网络(GAN) :用于图像生成或数据增强”
  • 容器内启动GUI界面相关问题。
  • PostgreSQL中的Replication_slot
  • YOLOv11改进:视觉变换器SwinTransformer目标检测网络
  • 泰迪杯特等奖案例学习资料:基于多模态融合与边缘计算的智能温室环境调控系统
  • Java 多线程进阶:什么是线程安全?
  • OpenCV 图形API(75)图像与通道拼接函数-----将 4 个单通道图像矩阵 (GMat) 合并为一个 4 通道的多通道图像矩阵函数merge4()
  • 【游戏ai】从强化学习开始自学游戏ai-2 使用IPPO自博弈对抗pongv3环境
  • linux jounery 日志相关问题
  • 今年五一假期出游人群规模预计比去年提升8%,哪里最热门?
  • 八成盈利,2024年沪市主板公司实现净利润4.35万亿元
  • 空调+零食助顶级赛马备战,上海环球马术冠军赛即将焕新登场
  • 徐徕任上海浦东新区副区长
  • 解放日报社论:只争朝夕、不负重托,加快建成具有全球影响力的科技创新高地
  • 俄罗斯纪念卫国战争胜利80周年阅兵式首次彩排在莫斯科举行