-
Notifications
You must be signed in to change notification settings - Fork 174
Open
Description
单例模式,分两种加载模式,下面介绍下 Go 里面怎么使用单例模式。
饿汉模式
适合程序初始化时就确定怎么加载实例的情况
package singleton
// Singleton 饿汉式单例
type Singleton struct{}
var singleton *Singleton
func init() {
singleton = &Singleton{}
}
// GetInstance 获取实例
func GetInstance() *Singleton {
return singleton
}
懒汉模式
延迟加载,适合根据传入参数实现定制化的初始化操作。
package singleton
import (
"sync"
"sync/atomic"
)
type singleton struct {}
var (
initialized uint32
instance *singleton
mu sync.Mutex
)
func GetInstance() *singleton {
if atomic.LoadUint32(&initialized) == 1 { // 原子操作
return instance
}
mu.Lock()
defer mu.Unlock()
if initialized == 0 {
instance = &singleton{}
atomic.StoreUint32(&initialized, 1)
}
return instance
}
上面通过了atomic 和 mutex 进行双重检查,保证线程安全,不过可以利用 sync.Once 实现更简洁的版本,这一版最好也记住,有可能面试的时候就不让你用sync.Once实现,sync.Once 内部也是维护了个标志为,用atomic 判断它是否已经执行过函数。
Java 里的线程安全的单例也是这么通过volatile+synchronized 双锁检查实现的。
简洁版的懒汉模式单例
package singleton
type singleton struct {}
var instance *singleton
var once sync.Once
func GetInstance() *singleton {
once.Do(func() {
instance = &singleton{}
})
return instance
}
这里直接上的代码,没有什么废话,如果想看故事版的,可以访问最简单的单例模式,Go版本的实现你写对了吗?
linxinemily
Metadata
Metadata
Assignees
Labels
No labels