5

go设计模式之单例模式浅谈

 3 years ago
source link: https://studygolang.com/articles/35024
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

go设计模式之单例模式浅谈

go_hiro · 3天之前 · 161 次点击 · 预计阅读时间 2 分钟 · 大约8小时之前 开始浏览    

保证一个类仅有一个实例,并提供一个访问它的全局访问点。

单例实现有两种方式,分别是饿汉模式和懒汉模式,下面分别说明:

1.饿汉模式

type single struct {}
var instance *single
instance = &single{}

func GetSingle() *single {
    return instance
}

饿汉模式存在问题,instance压根没使用都会自动创建,这时懒汉模式就排上用场了

2.懒汉模式

1)非安全模式

//非安全模式
type single struct {}
var instance *single
func GetSingle() *single {
    if instance == nil {
        instance = &single{}
    }
    return instance
}

懒汉模式只有通过第一次调用GetSingle时才会创建,但上面GetSingle在多线程环境下是不安全的,如下:

type single struct {}
var instance *single
func GetSingle() *single {
    if instance == nil {
        fmt.Println("创建实列")
        instance = &single{}
    }
    return instance
}

//通过开启1000个协程,发现会打印出多个"创建实列"
for i := 0; i < 1000; i++{
    go GetSingle()
}

通过测试,发现会打印出多个"创建实列",即实列被创建了多次,我们可以通过枷锁的方式,保证GetSingle每次只能被一个协程访问

2)安全模式

type single struct {}
var instance *single
var m sync.Mutex
func GetSingle() *single {
    if instance == nil {
        m.Lock() //加锁,防止多线程异常
        if instance == nil {
            instance = &single{}
        }
        m.Unlock()
    }
    return instance
}

3)go专属单例实现

go语言有一个once.Do函数,保证函数只被执行一次,利用这一特性,来实现单例, once.Do是多协程安全的

type single struct {}
var instance *single
var once sync.Once
func GetSingle() *single {
    once.Do(func() {
        instance= &single{}
    })
    return instance
}

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK