GO语言设计模式-单例模式
什么是单例模式
单例模式是一种常用的软件设计模式,其定义是单例对象的类只能允许一个实例存在。
许多时候整个系统只需要拥有一个的全局对象,这样有利于我们协调系统整体的行为。比如在数据库连接中,我们只希望进程内所有的访问DB都是通过一个数据库连接进行的。
普通实现-并发不work
单例模式第一种实现方式
// 单例模式 package design import "fmt" type singleton struct { Name string } var instance *singleton func GetInstance() *singleton { if instance == nil { fmt.Println("init") //这里每实例化一次,输出init instance = &singleton{} } return instance }
这种实现方式在没有并发的情况下是正常工作的
package main import ( "learn/design" ) func main() { //串行执行正常 design.GetInstance() //输出init design.GetInstance() //不输出init }
但是一旦出现并发的情况,这种实现方式是就不能正常工作了
package main import ( "learn/design" "sync" ) func main() { //并发不正常 var wg sync.WaitGroup for i := 0; i < 10; i++ { wg.Add(1) go func() { defer wg.Done() design.GetInstance() //每一次,均输出init }() } wg.Wait() }
once 方式实现-并发work
上面实现的第一种方式在并发情况下并不能正常work,这里使用once方式支持并发执行一次,一般比较常用的就是这种方式了
// 单例模式 package design import ( "fmt" "sync" ) type singleton struct { Name string } var instance *singleton var once sync.Once func GetInstance() *singleton { if instance == nil { once.Do(func() { fmt.Println("init") //这里每实例化一次,输出init instance = &singleton{} }) } return instance }
sync.Mutex锁方式实现-并发work
除了上面的使用once方式实现,还可以使用锁实现并发下只实例化一次
// 单例模式 package design import ( "fmt" "sync" ) type singleton struct { Name string } var instance *singleton var mu sync.Mutex var isSuccess = 0 func GetInstance() *singleton { if isSuccess == 1 { return instance } mu.Lock() defer mu.Unlock() if isSuccess == 0 { fmt.Println("init") //这里每实例化一次,输出init instance = &singleton{} isSuccess = 1 } return instance }
No Leanote account? Sign up now.