文章目录

  • 单例模式
    • 定义
    • 特点
    • 使用原因
    • 缺点
    • 模式介绍
      • 懒汉模式
        • 同步锁实现
        • dispatch_once
      • 饿汉模式
        • 实现
    • 总结
      • 懒汉模式
        • 优点
        • 缺点
      • 饿汉模式
        • 优点
        • 缺点

单例模式

定义

单例模式,简单的说就是一个类始终只对应同一个对象,每次获取这个类的对象获得的都是同一个实例

如果一个类始终只能创建一个实例,那么这个类被称为单例类。单例类只有一个全局的接口来访问这个实例。当第一次载入的时候,他通常使用延迟加载的方创建唯一单例。在程序中一个单例只初始化一次,为了保证在使用中始终存在,单例类的存储是在存储器的全局区域,在编译时分配内存,只要程序在运行单例就始终存在,占用内存。在APP结束运行后释放这部分内存。但是在系统方法中,存在未知的自动释放池,如果对一个对象进行自动释放的话,可能进入未知的释放池,出现内存问题。即为单例模式不能自动释放的原因

特点

  1. 单例类是一个类,这个类创造出的对象是单例对象
  2. 单例对象使用类方法创建
  3. 单例一旦被创建出来,直到程序结束运行才会释放
  4. 单例不用我们来管理内存,内存会随着程序关闭而被释放

使用原因

节省内存,防止一个实例被重复创建从而占用内存空间。

缺点

  • 全局状态:可能导致全局状态的存在,使得程序难以调试,一个地方修改容易导致很多地方发生变化
  • 难以拓展:单例模式的实例是固定的,难以拓展以支持多个实例,必须修改代码,使单例类丢失单例的特性
  • 隐藏依赖关系:可能会隐藏单例类的依赖关系,代码更加耦合。

模式介绍

懒汉模式

是一种常见的单例设计模式,其主要特点是在需要时在创建单例对象的实现,通过延迟对象的初始化来节省资源和提高性能。适用于访问量较小的情况,使用时间来换取空间

同步锁实现
#import "Person.h"@implementation Person
static id instance = nil;
+ (instancetype)sharedInstance {@synchronized (self) {if (!instance) {instance = [[super allocWithZone:NULL] init];}}return instance;
}
@end

这一段代码提供了一个全局访问点sharedInstace类方法提供给外部访问这个单例,在方法内部通过添加了一个同步锁,限制了同一时间只有一个线程访问临界区的代码。但是这里如果instance已经存在是没有必要进入锁的,所以可以再加个判断如下:

#import "Person.h"@implementation Person
static id instance = nil;
+ (instancetype)sharedInstance {if (!instance) {@synchronized (self) {if (!instance) {instance = [[super allocWithZone:NULL] init];}}}return instance;
}+ (instancetype)allocWithZone:(struct _NSZone *)zone {if (!instance) {@synchronized (self) {if (!instance) {instance = [super allocWithZone:zone];}}}return instance;
}- (id)copyWithZone:(NSZone *)zone {return self;
}- (id)mutableCopyWithZone:(NSZone *)zone {return self;
}
@end

对于allocWithZone的参数,传什么其实都无所谓,分配的内存区域不会改变
内层if的作用:假设有两个线程A和B同时调用了sharedInstance,线程A先一步获取锁,进入代码块,此时线程B等待锁释放,当线程A初始化instance后释放锁,B获得锁,如果没有内层if判断,会再次创建实例,破坏了单例的唯一性

dispatch_once

通过一个静态的dispatch_once变量来跟踪代码的执行状态,第一次调用时原子操作发现标记状态为未执行代码块,并原子性的将标记设为已执行,后续监测到标记为已执行,就会跳过该代码块。非常高效、没有阻塞开销

#import "Person.h"@implementation Person
static id instance = nil;
+ (instancetype)sharedInstance {static dispatch_once_t onceToken;dispatch_once(&onceToken, ^{instance = [[super allocWithZone:NULL] init];});return instance;
}+ (instancetype)allocWithZone:(struct _NSZone *)zone {static dispatch_once_t onceToken;dispatch_once(&onceToken, ^{instance = [super allocWithZone:zone];});return instance;
}- (id)copyWithZone:(NSZone *)zone {return self;
}- (id)mutableCopyWithZone:(NSZone *)zone {return self;
}
@end

我们打印出不同情况下的对象地址如下:
请添加图片描述

饿汉模式

在类加载过程就完成这个单例的创建和初始化

实现
#import "Person.h"@implementation Person
static id instance = nil;+ (void)load {instance = [[super allocWithZone:NULL] init];
}+ (instancetype)sharedInstance {return instance;
}+ (instancetype)allocWithZone:(struct _NSZone *)zone {return instance;
}- (instancetype)init {static dispatch_once_t onceToken;dispatch_once(&onceToken, ^{NSLog(@"init一次");});return self;
}- (id)copyWithZone:(NSZone *)zone {return self;
}- (id)mutableCopyWithZone:(NSZone *)zone {return self;
}@end

总结

懒汉模式

优点
  1. 延迟加载,节省资源,提高性能。
  2. 避免在程序启动时就创造不必要的对象,造成额外开销
  3. 可以通过加锁实现线程安全
缺点
  1. 为实现线程安全使用锁机制,可能会引起一些性能开销

饿汉模式

优点
  1. 实现简单,不需要考虑线程安全问题,实例在类加载时就已经创建了,所以不用考虑创建多个实例的风险
缺点
  1. 程序启动时就加载创建实例,可能会浪费资源,引起性能问题
  2. 如果单例对象的创建需要建立在某些外部前提下,那么不适合饿汉模式

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/96273.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/96273.shtml
英文地址,请注明出处:http://en.pswp.cn/web/96273.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[论文阅读] 算法 | 抗量子+紧凑!SM3-OTS:基于国产哈希算法的一次签名新方案

抗量子紧凑!SM3-OTS:基于国产哈希算法的一次签名新方案 论文信息信息类别具体内容论文原标题SM3-OTS: 基于国密算法SM3的紧凑型后量子一次签名方案主要作者杨亚涛、殷方锐、陈亮宇、潘登研究机构1. 北京电子科技学院 电子与通信工程系(北京 1…

C语言-指针用法概述

目录 1.指针基础概念 2. 指针与数组 3. 指针作为函数参数 4. 动态内存分配 5. 指针的高级用法 6. 常见错误与注意事项 7. 指针数组 vs. 数组指针 8.总结与建议 本文主要作为指针用法的复习,会对指针的大致用法进行举例和概述。 1.指针基础概念 ​什…

Java调用Whisper和Vosk语音识别(ASR)模型,实现高效实时语音识别(附源码)

简介 语音识别(Automatic Speech Recognition, ASR)是将人类的语音信号自动转换为对应文字的技术,它使计算机能够“听懂”人说的话,是人机语音交互的核心技术,广泛应用于智能助手、语音输入、客服系统等场景。 现在我…

第3周 机器学习课堂记录

1.学习问题的分类有监督的学习分类回归无监督学习聚类密度估计:确定输入空间中的数据的分布可视化:把高位空间中的数据投影到二维或三维空间强化学习不给定最优输出的示例,而是通过试错发现最优输出2.泛化versus过度拟合背景引入:…

消息队列(MQ)高级特性深度剖析:详解RabbitMQ与Kafka

一、引言:为什么需要关注高级特性? 在现代分布式系统架构中,消息队列(Message Queue)已成为不可或缺的核心组件。初级使用消息队列可能只需几行代码就能实现基本功能,但要真正发挥其在大规模生产环境中的威…

【GPT入门】第65课 vllm指定其他卡运行的方法,解决单卡CUDA不足的问题

【GPT入门】第65课 vllm指定其他卡运行的方法,解决单卡CUDA不足的问题1.原理说明:2.实践1.原理 要将 vllm 部署在第二张 GPU 卡上(设备编号为 1),只需在命令前添加 CUDA_VISIBLE_DE…

Spring Boot Actuator自定义指标与监控实践指南

Spring Boot Actuator自定义指标与监控实践指南 本篇文章以生产环境实战经验为主线,结合某电商系统的业务场景,讲解如何在Spring Boot Actuator中添加并暴露自定义指标,并使用Prometheus和Grafana进行完整的监控与告警配置。 一、业务场景描述…

Vue报错<template v-for=“option in cardOptions“ :key=“option.value“>

在Vue项目中遇到报错&#xff0c;原因是模板中使用了<template>标签内的v-for指令&#xff0c;而当前Vue版本不支持此用法。解决方案是移除<template>标签&#xff0c;直接在<el-option>上使用v-for。同时优化计算属性cardOptions&#xff0c;使其能够兼容历…

人工智能学习:Transformer结构中的规范化层(层归一化)

Transformer结构中的规范化层(层归一化) 一、规范化层(层归一化)介绍 概念 层归一化(Layer Normalization) 是一种用于提高深度神经网络训练稳定性和加速收敛的技术,广泛应用于现代深度学习模型中,尤其是在Transformer等序列建模网络中。它通过对每一层的输出进行归一化…

盼之代售 最新版 decode__1174

声明 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01; 逆向分析 部分python代码 cp1 execj…

Transformer系列 | Pytorch复现Transformer

&#x1f368; 本文为&#x1f517;365天深度学习训练营中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 一、Transformer和Seq2Seq 在之前的博客中我们学习了Seq2Seq(深度学习系列 | Seq2Seq端到端翻译模型)&#xff0c;知晓了Attention为RNN带来的优点。那么有没有…

【MySQL】常用SQL语句

介绍常用的DDL语句、DML语句基本语法分号结尾使用空格和缩进不区分大小写--或#注释单行内容 /*注释多行内容*/DDL数据定义语句&#xff1a;定义数据库、表、字段一、操作库-- 创建库create database db1;-- 创建库是否存在&#xff0c;不存在则创建create database if not exi…

云手机就是虚拟机吗?

云手机并非等同于虚拟机&#xff0c;尽管二者存在一定相似性&#xff0c;但有着诸多区别&#xff0c;以下从多个方面来分析&#xff1a;云手机是一种基于云计算技术&#xff0c;将云端服务器虚拟化为手机设备&#xff0c;用户能通过网络远程操控的虚拟手机服务&#xff0c;它从…

准确--Nginx 1.28.0 安装与配置流程

Nginx 1.28.0 安装与配置流程 1. 下载与解压 cd ~ wget http://nginx.org/download/nginx-1.28.0.tar.gz tar -zxvf nginx-1.28.0.tar.gz cd nginx-1.28.02. 配置编译参数 ./configure \--prefix/home/ynnewweb/nginx \--with-http_ssl_module \--with-http_gzip_static_module…

无标记点动捕新范式:Xsens系统助力人形机器人实现毫米级动作复刻

Xsen搭载Manus数据手套在机器人操作与机器学习中的应用当前&#xff0c;人形机器人正加速向工业装配、家庭陪护、仓储物流等场景渗透&#xff0c;而 “如何让机器人的动作既符合人类运动规律&#xff0c;又能实现高精度执行” 成为制约其落地的核心瓶颈。Xsens 高精度全身动捕系…

mysql57超管root忘记密码怎么办

目录 背景 1.首先停止数据库 2.使用免密模式启动 3.修改密码 3.1刷新权限配置 3.2修改密码 4.杀掉mysql 5.重新正常启动mysql 6.查看mysql状态 7.验证 7.1首先服务器本地验证 7.2远程验证 背景 数据库密码忘记了,急的抓耳挠腮,怎么也想不起来,于是就开始重置吧 1.…

RESTful API:@RequestParam与@PathVariable实战对比

RequestParam vs PathVariable 在删除和查找操作中的使用差异 在项目实战中&#xff0c;选择使用 RequestParam 还是 PathVariable 来接收ID参数&#xff0c;通常基于以下几个考虑因素&#xff1a; 1. RESTful API 设计原则 查找操作使用 PathVariable GetMapping("/depts…

剧本杀小程序系统开发:开启沉浸式社交娱乐新纪元

在当今数字化浪潮席卷的时代&#xff0c;社交娱乐方式正经历着前所未有的变革。剧本杀&#xff0c;这一融合了角色扮演、推理悬疑与社交互动的线下娱乐项目&#xff0c;近年来迅速风靡全国&#xff0c;成为年轻人热衷的社交新宠。而随着移动互联网的蓬勃发展&#xff0c;剧本杀…

中线安防保护器,也叫终端电气综合治理保护设备为现代生活筑起安全防线

中线安防保护器&#xff08;Neutral Line Protection Device&#xff0c;简称NLPD&#xff09;是一种专门用于监测和保护电力系统中性线的安全装置。中线安防保护器的基本原理为:通过电流检测环节采集系统中性线上过电流信息&#xff0c; 经控制器快速计算并提取各次谐波电流的…

Spring Cloud Alibaba快速入门02-Nacos配置中心(下)

文章目录前言配置中心 - 数据隔离示例1.先创建命名空间2.创建配置3.克隆配置4.动态切换环境5.yml多文档模式spring.profiles.activedevspring.profiles.activetest总结前言 上一章简单了解了Nacos配置中心的基本用法&#xff0c;这一章将开始Nacos配置中心的实战案例。 配置中…