面试题答案
一键面试原理
在Go语言中,sync.Once
实现单例模式的原理基于其内部的一个状态标志和一个互斥锁。当第一次调用 Once.Do(f)
时,Once
结构体中的状态标志会表明该操作尚未执行,此时互斥锁会被锁定,以确保只有一个 goroutine 能执行 f
函数。一旦 f
函数执行完毕,状态标志会被更新为已执行,后续再有调用 Once.Do(f)
时,由于状态标志已表明操作已执行,就不会再次执行 f
函数,从而保证了单例的唯一性。
代码示例
package main
import (
"fmt"
"sync"
)
type Singleton struct {
Data string
}
var instance *Singleton
var once sync.Once
func GetInstance() *Singleton {
once.Do(func() {
instance = &Singleton{
Data: "Initial data",
}
})
return instance
}
你可以在 main
函数中这样调用:
func main() {
var wg sync.WaitGroup
var instances []*Singleton
for i := 0; i < 10; i++ {
wg.Add(1)
go func() {
defer wg.Done()
instance := GetInstance()
instances = append(instances, instance)
}()
}
wg.Wait()
for _, inst := range instances {
fmt.Println(inst)
}
// 这里所有的 inst 都是同一个实例
}