使用懒惰模式的单例模式,使用双重检查加锁保证线程安全
代码实现
package singletonimport "sync"// Singleton 是单例模式接口,导出的
// 通过该接口可以避免 GetInstance 返回一个包私有类型的指针
type Singleton interface {foo()
}// singleton 是单例模式类,包私有的
type singleton struct{}func (s singleton) foo() {}var (instance *singletononce sync.Once
)//GetInstance 用于获取单例模式对象
func GetInstance() Singleton {once.Do(func() {instance = &singleton{}})return instance
}
单元测试
package singletonimport ("sync""testing"
)const parCount = 100func TestSingleton(t *testing.T) {ins1 := GetInstance()ins2 := GetInstance()if ins1 != ins2 {t.Fatal("instance is not equal")}
}func TestParallelSingleton(t *testing.T) {start := make(chan struct{})wg := sync.WaitGroup{}wg.Add(parCount)instances := [parCount]Singleton{}for i := 0; i < parCount; i++ {go func(index int) {//协程阻塞,等待channel被关闭才能继续运行<-startinstances[index] = GetInstance()wg.Done()}(i)}//关闭channel,所有协程同时开始运行,实现并行(parallel)close(start)wg.Wait()for i := 1; i < parCount; i++ {if instances[i] != instances[i-1] {t.Fatal("instance is not equal")}}
}