Golang设计模式之单例模式详细讲解
作者:Ch3n 发布时间:2024-02-20 01:10:16
单例模式
单例是一种创建型设计模式, 让你能够保证一个类只有一个实例, 并提供一个访问该实例的全局节点。
单例拥有与全局变量相同的优缺点。 尽管它们非常有用, 但却会破坏代码的模块化特性。
在某些其他上下文中, 你不能使用依赖于单例的类。 你也将必须使用单例类。 绝大多数情况下, 该限制会在创建单元测试时出现。
概念示例
通常而言, 单例实例会在结构体首次初始化时创建。 为了实现这一操作, 我们在结构体中定义一个 getInstance获取实例方法。 该方法将负责创建和返回单例实例。 创建后, 每次调用 getInstance时都会返回相同的单例实例。
协程方面又有什么需要注意的吗? 每当多个协程想要访问实例时, 单例结构体就必须返回相同的实例。 正因如此, 单例设计模式的实施工作很容易出错。 下方的例子表示了创建单例的正确方式。
一些值得注意的地方:
最开始时会有 nil检查, 确保 singleInstance单例实例在最开始时为空。 这是为了防止在每次调用 getInstance方法时都去执行消耗巨大的锁定操作。 如果检查不通过, 则就意味着 singleInstance字段已被填充。
singleInstance结构体将在锁定期间创建。
在获取到锁后还会有另一个 nil检查。 这是为了确保即便是有多个协程绕过了第一次检查, 也只能有一个可以创建单例实例。 否则, 所有协程都会创建自己的单例结构体实例。
single.go: 单例
package main
import (
"fmt"
"sync"
)
var lock = &sync.Mutex{}
type single struct {
}
var singleInstance *single
func getInstance() *single {
if singleInstance == nil {
lock.Lock()
defer lock.Unlock()
if singleInstance == nil {
fmt.Println("Creating single instance now.")
singleInstance = &single{}
} else {
fmt.Println("Single instance already created.")
}
} else {
fmt.Println("Single instance already created.")
}
return singleInstance
}
main.go: 客户端代码
package main
import (
"fmt"
)
func main() {
for i := 0; i < 30; i++ {
go getInstance()
}
// Scanln is similar to Scan, but stops scanning at a newline and
// after the final item there must be a newline or EOF.
fmt.Scanln()
}
output.txt: 执行结果
Creating single instance now.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
来源:https://ch3nnn.blog.csdn.net/article/details/126905774


猜你喜欢
- 1.1 简介开启慢查询日志,可以让MySQL记录下查询超过指定时间的语句,通过定位分析性能的瓶颈,才能更好的优化数据库系统的性能。1.2 登
- 目录友情提示:性能优化指标数据库查询优化利用Queryset的惰性和缓存,避免重复查询一次查询所有需要的关联模型数据仅查询需要用到的数据使用
- 这里的Counter是指collections中的Counter,通过Counter可以实现字典的创建以及字典key出现频次的统计。然而,使
- 代码如下: public function fillzero(l1) if len(l1)=1 then fillzero="0&
- 如今,基本每个网站都会需要到Tab切换展示内容的滑动门效果应用,这种效果可以在更少的页面空间内,展示更多的网站内容,节约空间,方便用户集中操
- 背景最近用uni-app开发小程序项目时,部分需要持久化的内容没法像其他vuex中的state那样调用,所以想着自己实现一下类似vuex-p
- 在使用Ajax过程中,有时候总会遇到一些难题,浏览器兼容、编码、IE下的特殊处理等等,偶尔会搞的人头昏脑胀哭笑不得,这里列一些小贴士,或许有
- 最近了解下基于 Token 的身份验证,跟大伙分享下。很多大型网站也都在用,比如 Facebook,Twitter,Google+,Gith
- 在Web开发中,后端代码写起来其实是相当容易的。例如,我们编写一个REST API,用于创建一个Blog:@api@post('/a
- 本文实例讲述了Python多线程编程之多线程加锁操作。分享给大家供大家参考,具体如下:Python语言本身是支持多线程的,不像PHP语言。下
- 最近在研究雨哲软件采集程序的时候,需要获取真实软件地址时遇到了需要读取跳转页面跳转后的真实地址的问题。在网上找了很多方法,使用WinHttp
- 所谓产品其实最终展现在用户面前的只是界面而已,所谓界面绝大多数时候只包括两个部分:图片、文字。重视界面上的每一个像素和每一个文字是UED的基
- MigrationsDjango中对Model进行修改是件麻烦的事情,syncdb命令仅仅创建数据库里还没有的表,它并不对已存在的数据表进行
- 1.首先肯定是要安装Node.JSwindows cmd依次输入如下命令:cd C:\Program Files\nodejs\npm in
- 使用下面的命令检查是否安装有MySQL Server[root@localhost etc]# rpm -qa | grep mysql /
- python类型提示(type hint)在刷leetcode或者一些官方源码的时候,经常看到如下字样:class Solution:&nb
- ip正则式为:r'(([12][0-9][0-9]|[1-9][0-9]|[1-9])\.){3,3}([12][0-9][0-9]
- 本文实例讲述了Python机器学习之scikit-learn库中KNN算法的封装与使用方法。分享给大家供大家参考,具体如下:1、工具准备,p
- 何时使用单体 RESTful 服务对于很多初创公司来说,业务的早期我们更应该关注于业务价值的交付,而单体服务具有架构简单,部署简单,开发成本
- 这篇文章主要介绍了Python OpenCV视频截取并保存实现代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价