go语言实现单例模式
单例模式概念不再赘述,只阐述一些值得注意的点
- 一开始有个nil确认,确保singleInstance没有被初始化。如果没有这个确认的话,直接进入加锁阶段,会导致每次getInstance都要加锁,开销增加。如果确认不为nil,则直接返回对象
- singleInstance 在锁内创建
- 在第一个nil确认后加锁,为了确保在多个goroutine都通过第一个确实后,只有一个能够创建singleInstance,否则每个goroutine都会创建自己的实例。
package main
import (
"fmt"
"sync"
)
var lock = &sync.Mutex{} // 创建互锁
type single struct {} // 创建结构体
var singleInstance *single // 创建指针
func getInstance() *single {
if singleInstance == nil { //!!!注意这里check nil了两次
lock.Lock()
defer lock.Unlock()
if singleInstance == nil {
fmt.Println("创建单例")
singleInstance = &single{}
} else {
fmt.Println("单例对象已创建")
}
} else {
fmt.Println("单例对象已创建")
}
return singleInstance
}
func main() {
for i := 0; i < 5; i++ {
go getInstance()
}
fmt.Scanln()
// 不写scanln看不到输出
// Scanln is similar to Scan, but stops scanning at a newline and
// after the final item there must be a newline or EOF.
}