Go语言之单例模式
Posted 陈谋人
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Go语言之单例模式相关的知识,希望对你有一定的参考价值。
前言
单例模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象 。在过去的很长时间里,很多开发人员都习惯使用php快速开发功能强大的系统,并且大多数情况下都不需要担心内部事务如何工作,也不需要担心线程安全性和并发性,单例模式在php中应用广泛,然而Go语言太容易实现并发了,以至于它在很多地方被不正确的使用了。
常见问题
/**
* @program: Go
*
* @description:单例模式并发不安全写法,多个协程操作容易都将创建该manager类型的实例并相互覆盖。无法保证它将在此处返回哪个实例。
*
* @author: Mr.chen
*
* @create: 2020-09-03 16:49
**/
package main
import (
"fmt"
)
type manager struct{}
var m *manager
func Instance() *manager {
if m == nil {
m = new(manager)
}
return m
}
单例模式并发不安全写法,多个协程操作容易都将创建该manager类型的实例并相互覆盖。无法保证它将在此处返回哪个实例,难调试以及没发现错误
实践与修改
改进1:利用互斥锁来初始化manager,通过加锁把对该函数的并发调用变成了串行。在manager已经初始化的情况下,我们只是返回缓存的manager实例。在高并发下,多个访问只能获取一个manager实例,在性能损耗多,串行时间慢,可能会存在一定的瓶颈。
/**
* @program: Go
*
* @description:利用互斥锁来实现go语言中的单例模式
*
* @author: Mr.chen
*
* @create: 2020-09-03 17:22
**/
package main
import (
"fmt"
"sync"
)
var iMutex sync.Mutex
type manager struct{}
var m *manager
func Instance() *manager {
if m == nil {
iMutex.Lock()
defer iMutex.Unlock()
m = new(manager)
}
return m
}
/**
* @program: Go
*
* @description:利用sync.Once来实现go语言中的单例模式
*
* @author: Mr.chen
*
* @create: 2020-09-03 17:22
**/
package main
import (
"fmt"
"sync"
)
var once sync.Once
type manager struct{}
var m *manager
func Instance() *manager {
once.Do(func() {
m = &manager{}
})
return m
}
程序员在写代码的时候必须养成多学多问多思考的习惯,写代码要养成严谨的习惯,特别是涉及到并发和并行代码时,我们更需要对代码进行审查。
以上是关于Go语言之单例模式的主要内容,如果未能解决你的问题,请参考以下文章