单例模式是最简单的设计模式之一,它提供了创建对象的最佳方式。这种模式涉及到一个单一的结构体,该结构体负责创建自己的对象,同时确保只有单个对象被创建。即多次创建一个结构体的对象,得到的对象的存储地址永远与第一次创建对象的存储地址相同。
1初始化模式【类似C#的静态够着函数 】 在程序加载阶段init()创建对象实例,虽然保证线程安全,但是会减慢程序启动速度。如果对象实例不被调用,则会浪费一段内存空间。
type SingletonA struct {}
var instanceA *SingletonA
func init() {
instanceA = &SingletonA{}
}
func GetInstanceA() *SingletonA{
return instanceA
}
2.锁模式。为了解决锁带来的开销,因此使用sync.Once,其本质是通过原子性操作,只有满足一定条件时才进行对象创建。
type SingletonD struct {}
var instanceD *SingletonD
var once sync.Once
func GetInstanceD() *SingletonD{
once.Do(func() {
instanceD = &SingletonD{}
})
return instanceD
}
查看sync.Once的源码实现,其本质时原子性操作,与下面方式等同。
type SingletonF struct {}
var instanceF *SingletonF
var tmp uint32
func GetInstanceF() *SingletonF{
if atomic.LoadUint32(&tmp) == 1 {
return instanceF
}
mx.Lock()
defer mx.Unlock()
if tmp == 0 {
instanceF = &SingletonF{}
atomic.StoreUint32(&tmp,1)
}
return instanceF
}