学习系列:5种常见的单例模式变体及其实现方式
单例模式是一种创建型设计模式,它保证一个类只有一个实例,并提供了一个全局访问点。在实际应用中,我们可能会遇到一些特殊情况,需要对单例模式进行一些变体,以满足不同的需求。下面介绍几种常见的单例模式变体。
1. 懒汉式单例模式
懒汉式单例模式是指在第一次调用时才创建实例。这种方式可以避免在程序启动时就创建实例,从而提高程序的启动速度。但是,由于在多线程环境下可能会出现竞争条件,因此需要进行同步处理,以保证线程安全性。
下面是一个简单的懒汉式单例模式的实现:
class Singleton:__instance = None@staticmethoddef get_instance():if Singleton.__instance is None:Singleton()return Singleton.__instancedef __init__(self):if Singleton.__instance is not None:raise Exception("This class is a singleton!")else:Singleton.__instance = self
在这个实现中,我们使用了一个静态变量 __instance 来保存实例。在 get_instance 方法中,如果实例不存在,则创建一个新的实例并返回;否则直接返回已有的实例。在 __init__ 方法中,我们检查 __instance 是否已经存在,如果存在则抛出异常,否则将当前实例赋值给 __instance。
2. 饿汉式单例模式
饿汉式单例模式是指在类加载时就创建实例。这种方式可以避免在多线程环境下出现竞争条件,从而保证线程安全性。但是,由于在程序启动时就创建实例,可能会导致程序启动速度变慢。
下面是一个简单的饿汉式单例模式的实现:
class Singleton:__instance = Singleton()@staticmethoddef get_instance():return Singleton.__instance
在这个实现中,我们使用了一个静态变量 __instance 来保存实例。在类加载时,就创建了一个新的实例,并将其赋值给 __instance。在 get_instance 方法中,我们直接返回 __instance。
3. 双重检查锁单例模式
双重检查锁单例模式是在懒汉式单例模式的基础上增加了同步锁,以提高线程安全性。在多线程环境下,可能会出现多个线程同时调用 get_instance 方法的情况,如果没有同步锁,就会导致创建多个实例的问题。使用同步锁可以避免这个问题,但是会影响程序的性能。
下面是一个简单的双重检查锁单例模式的实现:
import threadingclass Singleton:__instance = None__lock = threading.Lock()@staticmethoddef get_instance():if Singleton.__instance is None:with Singleton.__lock:if Singleton.__instance is None:Singleton()return Singleton.__instancedef __init__(self):if Singleton.__instance is not None:raise Exception("This class is a singleton!")else:Singleton.__instance = self
在这个实现中,我们使用了一个静态变量 __instance 来保存实例,以及一个同步锁 __lock。在 get_instance 方法中,我们首先检查 __instance 是否已经存在,如果不存在,则获取同步锁,并再次检查 __instance 是否已经存在。如果不存在,则创建一个新的实例,并将其赋值给 __instance。在 __init__ 方法中,我们检查 __instance 是否已经存在,如果存在则抛出异常,否则将当前实例赋值给 __instance。
4. 静态内部类单例模式
静态内部类单例模式是利用静态内部类的特性,在类加载时创建实例,保证线程安全性。这种方式可以避免在程序启动时就创建实例,从而提高程序的启动速度。
下面是一个简单的静态内部类单例模式的实现:
class Singleton:class __Singleton:def __init__(self):self.value = Nonedef __str__(self):return "{0!r} {1}".format(self, self.value)__instance = Nonedef __new__(cls):if not Singleton.__instance:Singleton.__instance = Singleton.__Singleton()return Singleton.__instancedef __getattr__(self, name):return getattr(self.__instance, name)def __setattr__(self, name):return setattr(self.__instance, name)
在这个实现中,我们使用了一个静态内部类 __Singleton 来保存实例。在 __new__ 方法中,我们首先检查 __instance 是否已经存在,如果不存在,则创建一个新的实例,并将其赋值给 __instance。在 __getattr__ 和 __setattr__ 方法中,我们将属性的访问委托给 __instance。
5. 枚举单例模式
枚举单例模式是利用枚举类型的特性,保证只有一个实例,并且可以防止反射和序列化攻击。这种方式可以避免在程序启动时就创建实例,从而提高程序的启动速度。
下面是一个简单的枚举单例模式的实现:
from enum import Enumclass Singleton(Enum):INSTANCE = 1
在这个实现中,我们定义了一个枚举类型 Singleton,其中只有一个枚举值 INSTANCE。由于枚举类型的特性,保证只有一个实例,并且可以防止反射和序列化攻击。在使用时,我们可以直接使用枚举值 Singleton.INSTANCE 来访问单例实例。
总之,单例模式是一种非常有用的设计模式,可以帮助我们在程序中创建唯一的实例,并提供一个全局访问点。在实际应用中,我们可能会遇到一些特殊情况,需要对单例模式进行一些变体,以满足不同的需求。
相关文章:
学习系列:5种常见的单例模式变体及其实现方式
单例模式是一种创建型设计模式,它保证一个类只有一个实例,并提供了一个全局访问点。在实际应用中,我们可能会遇到一些特殊情况,需要对单例模式进行一些变体,以满足不同的需求。下面介绍几种常见的单例模式变体。 1. 懒…...
三菱FX5U系列PLC之间进行简易PLC间链接功能的具体方法
三菱FX5U系列PLC之间进行简易PLC间链接功能的具体方法 功能介绍: 在最多8台FX5U或者FX3U PLC之间通过RS-485通信方式连接,进行软元件相互链接的功能。 接线注意事项: 根据链接模式和所使用的从站数量的不同,链接软元件的占用点数也有所变化。根据链接软元件的起始编号,对占…...
基于DBACAN的道路轨迹点聚类
目录 前言道路栅格化轨迹聚类参考资料 前言 很多针对道路轨迹的挖掘项目前期都需要对道路进行一段一段的分割成路段,然后对每一个路段来单独进行考察,如设定路段限速标识,超速概率等,如何对道路进行划分,其实是一个很…...
【项目】接入飞书平台
前言 项目有和飞书打通的需求,因为是第一次打通,摸索过程还是花了些时间的,现在相关笔记分享给大家。 步骤 1、熟悉开发文档 熟悉飞书的开发文档:开发文档 ,找到你需要的接口,拿我为例,我需…...
c++11 标准模板(STL)(std::ios_base)(三)
定义于头文件 <ios> class ios_base; 类 ios_base 是作为所有 I/O 流类的基类工作的多用途类。它维护数种数据: 1) 状态信息:流状态标志; 2) 控制信息:控制输入和输出序列格式化和感染的本地环境的标志; 3)…...
在线协同办公小程序开发搭建开发环境
目录 介绍 开发环境说明 虚拟机 原因 VirtualBox虚拟机 VMware虚拟机v15 安装MySQL数据库 安装步骤 导入EMOS系统数据库 安装MongoDB数据库 启动Navicat,选择创建MongoDB连接 创建用户 搭建Redis数据库 配置Maven 安装IDEA插件 Lombok插件 …...
【编译、链接、装载六】汇编——目标文件
【编译和链接六】汇编——目标文件 一、目标文件_存储格式1、生成目标文件2、目标文件存储格式3、file查看文件格式 二、查看目标文件的内部结构——objdump三、代码段四、 数据段和只读数据段五、 ELF文件结构描述1、头文件2、段表2.1、重定位表2.2、字符串表2.3、查看重定位表…...
王道计算机考研408计算机组成原理汇总(下)
提示:真正的英雄是明白世界的残酷,也遭受了社会带给他的苦难,他依然能用心的说“我热爱这个世界,我愿竭尽所能去为我的世界而好好战斗 文章目录 前言4.1.1 指令格式4.1.2 扩展操作码指令格式4.2.1 指令寻址4.2.2 数据寻址4.2.3 偏移寻址4.2.4 堆栈寻址汇总前言4.3.1 高级语…...
偏向锁、轻量级锁、重量级锁、自旋锁、自适应自旋锁
1. 偏向锁 偏向锁就是在运行过程中,对象的锁偏向某个线程。即在开启偏向锁机制的情况下,某个线程获得锁,当该线程下次再想要获得锁时,不需要重新申请获得锁(即忽略synchronized关键词),直接就可…...
Delta 一个新的 git diff 对比显示工具
目录 介绍git diff 介绍delta介绍 一、安装1.下载 Git2.下载 delta3.解压4.修改配置文件5. 修改主题6.其他配置和说明 二、对比命令1.在项目中 git diff 常用命令2.对比电脑上两个文件3.对比电脑上的两个文件夹 三、在Git 命令行中使用效果四、在idea 的Terminal命令行中使用效…...
C# 二进制序列化和反序列化示例
.NET框架提供了两种种串行化的方式: 1、是使用BinaryFormatter进行串行化; 2、使用XmlSerializer进行串行化。 第一种方式提供了一个简单的二进制数据流以及某些附加的类型信息,而第二种将数据流格式化为XML存储。可以使用[Serializable]属…...
【CSS】文字扫光 | 渐变光
码来 可调整角度与颜色值来改变效果 <p class"gf-gx-color">我是帅哥</p> <style>.gf-gx-color {background: -webkit-linear-gradient(135deg,red,red 25%,red 50%,#fff 55%,red 60%,red 80%,red 95%,red);-webkit-text-fill-color: transparen…...
Overhaul Distillation(ICCV 2019)原理与代码解析
paper:A Comprehensive Overhaul of Feature Distillation official implementation:GitHub - clovaai/overhaul-distillation: Official PyTorch implementation of "A Comprehensive Overhaul of Feature Distillation" (ICCV 2019) 本文的…...
<Linux开发>驱动开发 -之-内核定时器与中断
<Linux开发>驱动开发 -之-内核定时器与中断 交叉编译环境搭建: <Linux开发> linux开发工具-之-交叉编译环境搭建 uboot移植可参考以下: <Linux开发> -之-系统移植 uboot移植过程详…...
希尔贝壳邀您参加2023深圳国际人工智能展览会
2023深圳国际人工智能展览会“AIE”将于2023年5月16-18日在深圳国际会展中心 (宝安)举办,希尔贝壳受邀参加,展位号:A331。 伴随着智能行业的快速发展,展会已被越来越多的企业列入每年必选展会,也成为各采购商选购的理…...
设计优质微信小程序的实用指南!
微信小程序是一种快速发展的应用形式,设计良好的小程序能够提升用户体验并吸引更多的用户。在设计微信小程序时,有一些关键的指南可以帮助我们做出出色的设计。以下是即时设计总结的一些设计指南,希望能对准备设计微信小程序的人有所帮助。 …...
大数据期末总结
文章目录 一、这学期分别学习了Scala、spark、spring、SpringMvc、SpringBoot1、scala2、spark3、spring4、SpringMvc5、SpringBoot 二、总结 一、这学期分别学习了Scala、spark、spring、SpringMvc、SpringBoot 1、scala Scala是一门基于JVM的编程语言,具有强大的…...
selenium面试题总结
今天有同学问到seleinum面试的时候会问到的问题,随便想了想,暂时纪录一下。欢迎大家在评论中提供更多问题。 1.selenium中如何判断元素是否存在? selenium中没有提供原生的方法判断元素是否存在,一般我们可以通过定位元素异常捕获…...
⑧电子产品拆解分析-1拖4USB拓展坞
⑧电子产品拆解分析-1拖4USB拓展坞 一、功能介绍二、电路分析以及器件作用1、内部电路拆解三、参考资料学习一、功能介绍 ①USB2.0一拖四通讯;②具备OTG功能,可适配大部分USB接口设备;二、电路分析以及器件作用 1、内部电路拆解 分析:❤️ ❤️ ❤️ 主控是MA8601 USB 2.0…...
月度精华汇总 | 最新XR行业资讯、场景案例、活动都在这一篇里啦!
在过去的一个月中,平行云为您带来了关于XR领域的一系列精彩文章,涵盖了行业资讯、应用案例,市场互动,帮助您掌握XR领域最新动态,了解实时云渲染、Cloud XR技术的价值,以及平行云实时云渲染解决方案LarkX…...
大数据学习栈记——Neo4j的安装与使用
本文介绍图数据库Neofj的安装与使用,操作系统:Ubuntu24.04,Neofj版本:2025.04.0。 Apt安装 Neofj可以进行官网安装:Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...
python打卡day49
知识点回顾: 通道注意力模块复习空间注意力模块CBAM的定义 作业:尝试对今天的模型检查参数数目,并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...
树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法
树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作,无需更改相机配置。但是,一…...
《Playwright:微软的自动化测试工具详解》
Playwright 简介:声明内容来自网络,将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具,支持 Chrome、Firefox、Safari 等主流浏览器,提供多语言 API(Python、JavaScript、Java、.NET)。它的特点包括&a…...
Java - Mysql数据类型对应
Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...
算法笔记2
1.字符串拼接最好用StringBuilder,不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...
Mysql中select查询语句的执行过程
目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析(Parser) 2.4、执行sql 1. 预处理(Preprocessor) 2. 查询优化器(Optimizer) 3. 执行器…...
【Redis】笔记|第8节|大厂高并发缓存架构实战与优化
缓存架构 代码结构 代码详情 功能点: 多级缓存,先查本地缓存,再查Redis,最后才查数据库热点数据重建逻辑使用分布式锁,二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...
iview框架主题色的应用
1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题,无需引入,直接可…...
android13 app的触摸问题定位分析流程
一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...
