单例模式在系统设计中很常用,如数据库的连接对象等,该类只有一个实例存在,实现很简单,就是在创建实例时,判断一下,实例是否已经存在。
以下使用go语言实现单例模式
package main
import "fmt"
type Manager struct {
id int
}
func (m *Manager) Print() {
fmt.Println("我是独有的", m.id)
}
var m *Manager
func GetInstance() *Manager {
if m == nil {
m = &Manager{
id: 123,
}
}
return m
}
func main() {
manger :=GetInstance()
manger.Print()
}
以上,我们实现了一个简单的单例,但存在一个问题,在并发场景下,如果线程1获取到 m =nil,执行创建,线程2也获取到m =nil,也会执行实例创建,为了防止该问题出现,需要通过锁机制来解决该问题。在go语言下,有一个sync的包,他有一个对象once,有一个方法Do,内部实现了锁机制
再来看一下改进后的实现
package main
import (
"fmt"
"sync"
)
type Manager struct {
id int
}
func (m *Manager) Print() {
fmt.Println("我是独有的", m.id)
}
var m *Manager
var once sync.Once
func GetInstance() *Manager {
once.Do(func (){
m = &Manager{
id: 123,
}
})
return m
}
func main() {
manger :=GetInstance()
manger.Print()
}
以上实现了一个单例的demo, 看一下Do的方法
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()
}
}
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。