首先创建一个单例类:这个类只能被实例化一次
// 下面是一个单例类
type Singleton struct{
name string
}然后声明一个Singleton类的指针,作为唯一实例的指针
var singleton *Singleton写出这个单例类的创建方法,因为要保证整个程序只执行一次,不管是单线程下执行多次,还是多线程下多次创建,都只能有一份结构体的实例;使用sync包下的once。
这里顺便说一下once, once接口中传入一个方法,这个方法保证在整个程序运行期间只执行一次。
var once sync.Once
func GetSingleton(name string) *Singleton {
once.Do(func() {
singleton = &Singleton{name:name}
})
return singleton
}我们来测试一下这个单例实现,我们开启10个协程来调用GetSingleton方法,并且在主线程也调用,调用过程中,10个协程包括主线程都传入不同的名字,最后包括主线程在内的11个线程都去打印得到的singleton,看看是不是同一个:
func main() {
var wg sync.WaitGroup
wg.Add(10)
for i:=0; i<10; i++ {
go func(name string) {
s := GetSingleton(name)
fmt.Printf("%v\n", s)
wg.Done()
}(strconv.Itoa(i))
}
wg.Wait()
s := GetSingleton("main")
fmt.Printf("%v\n", s)
}输出测试结果:
&{0}
&{0}
&{0}
&{0}
&{0}
&{0}
&{0}
&{0}
&{0}
&{0}
&{0}证明是第一个协程实例化了单例类后,后面的协程都没有进行实例化。