单例模式,全局只有一个实例,无法再新建
饿汉模式:提前创建实例,提供一个对外方法,返回此实例
代码如下:
// Singleton 饿汉式单例, 都使用小写,无法导出,外部包没法直接创建
type singleton struct{
name string
}
// 通过一个导出类型暴露出去*singleton,由于Singleton内部属性无法导出,所以外部也没法创建(只能创建一个空对象)
type Singleton struct {
*singleton
}
var single *Singleton
func init() { // 提前创建好的一个实例,通过GetInstance方法,获取到的实例都是这个
single = &Singleton{&singleton{name: "test"}}
}
func (s *Singleton)GetName() string {
return s.name
}
// GetInstance 获取实例
func GetInstance() *Singleton {
return single
}
饱汉模式:熟称懒加载,就是在你使用实例的时候才去加载,对于懒汉模式,由于没有提前加载,在并发条件下,可能会出现两个协程同时去创建,一开始判断都是nil,会出现重复创建,所以需要进行双检(存在性检查,是否有别的协程已经调用创建,go的话我们用once.Do实现)
代码如下:
import (
"fmt"
"sync"
)
var (
lazySingleton *Singleton
once = &sync.Once{}
)
// GetLazyInstance 懒汉式
func GetLazyInstance() *Singleton {
if lazySingleton == nil { // 检测对象是否存在
once.Do(func() { //保证并发条件下值创建一次对象
fmt.Println("create")
lazySingleton = &Singleton{&singleton{name: "test lazy"}}
})
}
return lazySingleton
}
func main() {
wait := sync.WaitGroup{}
wait.Add(10)
for i:= 0;i<10;i++ {
go func() {
defer wait.Done()
s := create.GetLazyInstance()
fmt.Println(s.GetName())
}()
}
wait.Wait()
}