面试题答案
一键面试sync.Once的使用场景
- 单例模式:在Go语言中没有传统面向对象语言那样的类和构造函数概念,sync.Once 可用于实现单例模式,保证某个资源只初始化一次。例如数据库连接池,避免多次初始化连接池带来资源浪费和不一致问题。
- 延迟初始化:对于一些初始化开销较大的资源,如加载配置文件、初始化复杂数据结构等,使用sync.Once可实现延迟初始化,只有在真正需要使用该资源时才进行初始化。
示例代码
package main
import (
"fmt"
"sync"
)
// Singleton结构体
type Singleton struct {
data string
}
var instance *Singleton
var once sync.Once
// GetInstance获取单例实例
func GetInstance() *Singleton {
once.Do(func() {
instance = &Singleton{
data: "initial data",
}
})
return instance
}
在上述代码中,once.Do
确保 instance
只被初始化一次。无论多少个并发调用 GetInstance
函数,instance
只会在第一次调用 once.Do
时被初始化。 可以在 main
函数中测试:
func main() {
var wg sync.WaitGroup
for i := 0; i < 10; i++ {
wg.Add(1)
go func() {
defer wg.Done()
instance1 := GetInstance()
fmt.Println(instance1)
}()
}
wg.Wait()
}
此代码通过多个并发 goroutine 调用 GetInstance
函数,验证单例模式的正确性,每次输出的都是同一个 instance
。