当前位置:网站首页>go 4种单例模式
go 4种单例模式
2022-07-02 22:07:00 【给我一瓶冰阔洛】
懒汉式——非线程安全
非线程安全,指的是在多线程下可能会创建多次对象。
//使用结构体代替类
type Tool struct {
values int
}
//建立私有变量
var instance *Tool
//获取单例对象的方法,引用传递返回
func GetInstance() *Tool {
if instance == nil {
instance = new(Tool)
}
return instance
}在非线程安全的基本上,利用 Sync.Mutex 进行加锁保证线程安全,但由于每次调用该方法都进行了加锁操作,在性能上不是很高效
//锁对象
var lock sync.Mutex
//加锁保证线程安全
func GetInstance() *Tool {
lock.Lock()
defer lock.Unlock()
if instance == nil {
instance = new(Tool)
}
return instance
}饿汉式
直接创建好对象,不需要判断为空,同时也是线程安全,唯一的缺点是在导入包的同时会创建该对象,并持续占有在内存中。
Go语言饿汉式可以使用 init 函数,也可以使用全局变量。
type cfg struct {
}
var cfg *config
func init() {
cfg = new(config)
}
// NewConfig 提供获取实例的方法
func NewConfig() *config {
return cfg
}
type config struct {
}
//全局变量
var cfg *config = new(config)
// NewConfig 提供获取实例的方法
func NewConfig() *config {
return cfg
}双重检查
在懒汉式(线程安全)的基础上再进行优化,减少加锁的操作,保证线程安全的同时不影响性能。
//锁对象
var lock sync.Mutex
//第一次判断不加锁,第二次加锁保证线程安全,一旦对象建立后,获取对象就不用加锁了。
func GetInstance() *Tool {
if instance == nil {
lock.Lock()
if instance == nil {
instance = new(Tool)
}
lock.Unlock()
}
return instance
}sync.Once
通过 sync.Once 来确保创建对象的方法只执行一次
var once sync.Once
func GetInstance() *Tool {
once.Do(func() {
instance = new(Tool)
})
return instance
}sync.Once 内部本质上也是双重检查的方式,但在写法上会比自己写双重检查更简洁,以下是 Once 的源码
func (o *Once) Do(f func()) {
//判断是否执行过该方法,如果执行过则不执行
if atomic.LoadUint32(&o.done) == 1 {
return
}
// Slow-path.
o.m.Lock()
defer o.m.Unlock()
//进行加锁,再做一次判断,如果没有执行,则进行标志已经扫行并调用该方法
if o.done == 0 {
defer atomic.StoreUint32(&o.done, 1)
f()
}
}边栏推荐
- Notes on key vocabulary in the English original of the biography of jobs (10) [chapter eight]
- 【外刊】睡眠与减肥
- Introduction to database system Chapter 1 short answer questions - how was the final exam?
- 数学建模——图与网络模型及方法(一)
- 杰理之、产线装配环节【篇】
- [autosar-dcm] - 4.3-how UDS $22 and $2e services read and write NVM data
- 《乔布斯传》英文原著重点词汇笔记(九)【 chapter seven】
- 杰理之如何测试按键的误触率【篇】
- Market Research - current situation and future development trend of environmental friendly fireworks Market
- [LeetCode] 多数元素【169】
猜你喜欢

Simpleitk use - 3 Common operations

Radis:Linux上安装Redis(步骤)

Utilisation de simpletk - 4. Question étrange

Baidu AI Cloud - create a face recognition application

基于ASP.net的手机销售管理系统(二手手机销售管理系统)+ASP.NET+C#语言+VS2010+数据库可以用于课设、毕设学习

牛客网:龙与地下城游戏

SimpleITK使用——4. 奇怪的问题

数学建模——图与网络模型及方法(一)

Get off work on time! Episode 6 of Excel Collection - how to split and count document amounts

电商系统微服务架构
随机推荐
Methods of adding styles to native JS
基于ASP.net的手机销售管理系统(二手手机销售管理系统)+ASP.NET+C#语言+VS2010+数据库可以用于课设、毕设学习
Pointer and string
Objects and object variables
Basic concepts of image and deep understanding of yuv/rgb
`${}`的用法
原生js添加样式的方法
JS获取display为none的隐藏元素的宽度和高度的解决方案
NC50965 Largest Rectangle in a Histogram
How should programmers write logs
PMP项目整合管理
Market Research - current market situation and future development trend of marine wet exhaust hose
位的高阶运算
杰理之样机无触摸,拆机之后重新安装变正常【篇】
[LeetCode] 数组中的第K个最大元素【215】
Additional: [login information storage] and [login status verification]; (including: summarizing all the contents of [login information storage] and [login status verification] so far;)
佩服,竟然有人把高等数学这么晦涩难懂的科目,讲解得如此通俗易懂
[micro service sentinel] rewrite Sentinel's interface blockexceptionhandler
How can I use knockout's $parent/$root pseudovariables from inside a . computed() observable?
U++ 原始内存 学习笔记