【设计模式】创建型模式之单例模式(Golang实现)

定义

一个类只允许创建一个对象或实例,而且自行实例化并向整个系统提供该实例,这个类就是一个单例类,它提供全局访问的方法。这种设计模式叫单例设计模式,简称单例模式。

单例模式的要点:

  1. 某个类只能有一个实例
  2. 必须自行创建该实例
  3. 必须自行向整个系统提供该实例
    在这里插入图片描述
    时序图:
    在这里插入图片描述

用处

从业务概念上来看,有些数据在系统中只应该保留一份,就比较适合设计为单例类。比如,系统的配置信息。

使用场景:

  • 系统只需要一个实例对象,比如唯一的序列号生成器(业务方面),或是考虑到资源消耗太大而只允许创建一个对象
  • 客户调用类的单个实例只允许使用一个公共访问点,除了该公共访问点外,不能通过其他途径访问该实例

优缺点

优点:

  • 提供了对唯一实例的受控访问
  • 因为在系统的内存里只存在一个对象,所以可以节约系统资源,尤其是一些需要频繁创建和销毁的对象
  • 允许可变数目的实例,基于单例模式进行扩展

缺点:

  • 没有抽象层,很难扩展
  • 职责过重,在一定程度上违背了“单一职责原则”。因为单例类既充当了工厂角色,提供了工厂方法,同时又充当了产品角色,包含一些业务方法,将产品的创建和产品的本身的功能融合到一起。

单例模式的唯一性

  1. 进程间唯一:默认单例模式的唯一性就是基于进程的唯一性。因为编写的代码成为可执行文件后,当运行该可执行文件时,操作系统会启动一个进程,将该可执行文件从磁盘加载到自己的进程地址空间,该进程依次执行文件中的代码,比如代码里有一个创建student对象的语句,进程就会在地址空间里创建一个student对象。如果在一个进程中创建另一个进程,操作系统会给新进程分配新的地址空间,而且将旧地址空间的内容拷贝一份,包括代码和数据,这样新进程里有且只有一个student对象,旧进程里也有且只有一个student,但是这两个对象并不是同一个对象。
  2. 线程间唯一:通过获取线程id来实现。但是在golang里主要使用协程,而且协程的id并不会暴露出来。
  3. 集群环境间唯一(多进程):通过外部共享存储的锁进行,如文件。将单例对象序列化后存储到外部共享存储区里(比如文件),进程在使用该单例对象的时候,需要对该单例对象加锁,避免其他进程再获取,然后将该对象加载到内存里,反序列化为单例对象,使用完后还要从内存里删除,再存储回外部共享存储区,并释放锁。

如何实现

  • 构造函数是private访问权限
  • 考虑对象创建时的线程安全问题
  • 考虑是否支持延迟加载
  • 考虑getInstance的性能问题,比如是否有加锁等

实现方式

饿汉式

在类加载的时候实例就已经创建好了,实例的创建过程线程安全,不支持延迟加载

有两种实现方式,第一种是定义全局变量的时候创建实例,第二种是采用包的init函数创建实例

注意这里的Singleton类型也要是大写字母开头的,因为GetInstance方法是大写字母开头,表明包外可访问,那么该方法的返回值也需要包外可访问。

package singleton// 单例模式 饿汉式实现
type Singleton struct{}var singleton *Singleton//1.全局变量的实现方式
//var singleton1 = &Singleton{}
//2. 包的init函数实现方式
func init() {singleton = &Singleton{}
}func GetInstance() *Singleton {return singleton
}

懒汉式

在获取实例的时候再去创建,实例创建过程需要加锁,支持延迟加载,不支持高并发

不加锁

只是对懒汉式创建的一个理解,在GetInstnce方法里判断singleton是否为空,为空的话就去创建一个实例,否则直接返回该实例。

存在线程安全问题,高并发的时候会创建多个对象,不推荐使用。

package singleton// 单例模式 懒汉式实现 不加锁
type Singleton struct{}var singleton *Singletonfunc GetInstance() *Singleton {if singleton == nil {singleton = &Singleton{}}return singleton
}

给方法加锁

GetInstance整个方法进行加锁,确保并发安全,但是每一个对象创建的时候都需要进行加锁解锁,效率低

package singletonimport "sync"// 单例模式 懒汉式实现 方法锁
type Singleton struct{}var singleton *Singleton
var mu sync.Mutexfunc GetInstance() *Singleton {mu.Lock()defer mu.Unlock()if singleton == nil {singleton = &Singleton{}}return singleton
}

双重检测

在懒汉式的基础上,将方法的锁改为类级别的锁,相对于懒汉式的粒度更小,不用每次都去获取锁

借助sync.Once确保只创建一次

package singletonimport "sync"// 单例模式 懒汉式实现 双重检测
type LazySingleton struct{}var lazySingleton *LazySingleton
var once = &sync.Once{}func GetLazyInstance() *LazySingleton {if lazySingleton == nil {once.Do(func() {lazySingleton = &LazySingleton{}})}return lazySingleton
}

静态内部类

java的静态内部类,线程安全,延迟加载

枚举

java的枚举特性

测试性能

测试饿汉式的init实现方法和懒汉式的sync.Once实现方法

package singletonimport "testing"func BenchmarkGetInstanceParallel(b *testing.B) {b.RunParallel(func(pb *testing.PB) {for pb.Next() {if GetInstance() != GetInstance() {b.Errorf("test fail")}}})
}func BenchmarkGetLazyInstanceParallel(b *testing.B) {b.RunParallel(func(pb *testing.PB) {for pb.Next() {if GetLazyInstance() != GetLazyInstance() {b.Errorf("test fail")}}})
}

在对应的目录下执行:

go test -bench='Parallel$' -benchmem .

在这里插入图片描述
可以看出饿汉式的性能更好一点

参考链接
图解设计模式
Go设计模式
Golang单例模式

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

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

相关文章

烟火检测AI边缘计算智能分析网关V4在安防项目中的应用及特点

一、行业背景 随着社会和经济的发展,公共安全和私人安全的需求都在不断增长。人们需要更高效、更准确的安防手段来保障生命财产安全,而人工智能技术正好可以提供这种可能性,通过智能监控、人脸识别、行为分析等手段,大大提高了安防…

详细讲解MybatisPlus实现逻辑删除

目录 前言1. 基本知识2. 实战Demo3. 拓展 前言 对于MybatisPlus的相关知识可在我的博客进行搜索 对应的CRUD相关知识也可看我这篇文章:【Java项目】实战CRUD的功能整理(持续更新) 在讲述逻辑删除这个概念时,先引入另外一个概念&…

借助Gitee将typora图片上传CSDN

概述 前面已经发了一个如何借助Github将typora上的图片上传到csdn上,但这有个缺陷:需要科学上网才能加速查看已经上传到github上的图片,否则就会出现已经上传的图片,无法正常查看的问题 如何解决? 那就可以使用Gite…

wpf的资源路径

1、手动命名空间 xmlns:share"clr-namespace:***;assembly**" 2、资源文件 Pack URI 编译到本地程序集内的资源文件的 pack URI 使用以下授权和路径: 授权:application:///。 路径:资源文件的名称,包括其相对于本地…

坑记(HttpInputMessage)

一、背景知识 public interface HttpInputMessage extends HttpMessage Represents an HTTP input message, consisting of headers and a readable body.Typically implemented by an HTTP request on the server-side, or a response on the client-side.Since: 3.0 Author:…

dotJS 2018 - Anders Hejlsberg - TypeScript: JavaScript的静态类型

如何为像JavaScript这样的动态语言定义和实现静态类型系统,为什么要这样做呢? Anders Hejlsberg探讨了TypeScript是如何产生的,它与经典类型系统有何不同,以及即使你不喜欢类型,它也能给你带来好处。 视频地址: http…

Web端3D渲染引擎HOOPS SDK助力打造创新型3D测量软件

HOOPS SDK是全球领先的3D领域开发工具提供商Tech Soft 3D 打造的控件产品,HOOPS SDK包括4款3D软件开发工具,其中HOOPS Exchange是一款CAD数据转换工具,可读取和导入30多种CAD文件格式;HOOPS Communicator是一款专注于Web端工程图形…

NPS配置https访问web管理页面

因为NPS默认也支持http的访问,所以在部署完后就一直没在意这个事情。 因为服务器是暴露在公网内的,所以还是要安全一点才行。不然一旦远控的机器被破解了就很危险了 一、使用nginx反向代理访问 1、首先在nps的配置文件里关闭使用https选项,…

RPA财务机器人在厦门市海沧医院财务管理流程优化汇总的应用RPA全球生态 2024-01-05 17:27 发表于河北

目前国内外研究人员对于RPA机器人在财务管理流程优化领域中的应用研究层出不穷,但现有研究成果主要集中在财务业务单一领域,缺乏财务管理整体流程一体化管控的研究。RPA机器人的功能绝非单一的财务业务处理,无论从自身技术发展,或…

Retrofit2 + Hilt + MVVM + 协程 + Paging3 + SmartRefreshLayout 整合 使用

前言 Kotlin Android 框架 Jetpack相关库 MVVM 整合 使用。 1、Retrofit2 Hilt MVVM 2、Retrofit2 Hilt MVVM 协程 3、Retrofit2 Hilt MVVM 协程 Paging3 SmartRefreshLayout 效果图 源码地址 GitHub - LanSeLianMa/Retrofit2HiltMVVMCoroutine: Kotlin Andro…

jmeter监控服务器资源使用情况

GitHub - undera/perfmon-agent: Server metrics fetching agent, based on SIGAR 下载安装包:ServerAgent-2.2.3.zip 解压先 启动,如果是windows运行startAgent.bat,如果是linux运行startAgent.sh 注意:linux上注意权限的问题…

STM32蓝牙小车、红外循迹小车、超声波避障小车项目设计

一、前言 本文旨在分享我学习STM32的过程中,为了强化学习成果,试着制作一些实训项目。最开始做的就是STM32蓝牙小车、STM32红外循迹小车、STM32超声波避障小车。 相信看完本文的你,一定可以亲手制作一辆属于自己的智能小车! 注&am…

03 - 系统调用

---- 整理自 王利涛老师 课程 实验环境:宅学部落 www.zhaixue.cc 文章目录 1. 系统调用基本概念1.1 一个系统调用的例子1.2 什么是系统调用?软件复用的角度 2. 软中断:系统调用的入口2.1 权限管理2.2 系统调用号2.4 man 2 syscall2.5 实验&am…

优化 ParamValidator,让编辑器Pycharm智能提示校验方法

目录 一、前置说明1、总体目录2、相关回顾3、本节目标 二、操作步骤1、项目目录2、代码实现3、测试代码4、日志输出 三、后置说明1、要点小结2、下节准备 一、前置说明 1、总体目录 《 pyparamvalidate 参数校验器,从编码到发布全过程》 2、相关回顾 基于 Valid…

基于JavaWeb+BS架构+SpringBoot+Vue基于web的多媒体素材管理系统的设计和实现

基于JavaWebBS架构SpringBootVue基于web的多媒体素材管理系统的设计和实现 文末获取源码Lun文目录前言主要技术系统设计功能截图订阅经典源码专栏Java项目精品实战案例《500套》 源码获取 文末获取源码 Lun文目录 1 绪 论 1 1.1选题背景与意义 1 1.1 研究背景 1 1.2 研究意义…

网络安全工具:通过监控分析日志数据保护企业网络

由于混合工作模式的兴起以及业务运营向云环境的迁移,企业网络变得更加分散和复杂,仅安装外围安全解决方案只会创建一个基本的防御层,系统、服务器和其他网络实体会生成记录所有网络活动的日志。集中式日志管理系统可以帮助管理员自动监控网络…

手机直连卫星及NTN简介

一、手机直连卫星的发展现状 近日,华为推出了支持北斗卫星短报文的Mate 50旗舰机、P60系列,苹果也跟Globalstar(全球星)合作推出了支持卫星求救的iPhone14,最亮眼的还是华为的。这几款产品揭开了卫星通信探索消费领域…

Spring MVC 参数传递和JSON数据处理

参数传递 ModelAndView传递 编写controller Controller RequestMapping("/account") public class AccountController { ​//也可以不创建ModelAndView,直接在参数中指定RequestMapping(value "/findAccount9")public ModelAndView findAccou…

美国证券交易委员会 X 账户被黑,引发比特币市场震荡

Bleeping Computer 网站消息,威胁攻击者成功“占领”了美国证券交易委员会的 X 账户,并发布一条关于批准比特币 ETF 在证券交易所上市的虚假公告。 帖子原文:今天,美国证券交易委员会批准比特币 ETF 在注册的国家证券交易所上市&a…

MySQL:索引失效场景总结

1 执行计划查索引 通过执行计划命令可以查看查询语句使用了什么索引。 EXPLAIN SELECT * FROM ods_finebi_area WHERE areaName = 福建 执行查询计划后,key列的值就是被使用的索引的名称,若key列没有值表示查询未使用索引。 2 在什么列上创建索引 (1)列经常被用于where…