面试题答案
一键面试- 延迟初始化的具体实现机制:
sync.Once
类型只有一个方法Do
,其签名为func (o *Once) Do(f func())
。- 当第一次调用
Do
方法时,它会执行传入的函数f
,这个函数f
负责初始化资源。sync.Once
内部通过一个done
标志和一个互斥锁mu
来实现这个机制。第一次调用Do
时,done
为false
,互斥锁mu
确保只有一个goroutine能进入临界区执行f
,执行完f
后,done
被设置为true
。后续调用Do
时,若done
为true
,则直接返回,不会再执行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
}
func main() {
var wg sync.WaitGroup
numGoroutines := 10
for i := 0; i < numGoroutines; i++ {
wg.Add(1)
go func() {
defer wg.Done()
singleton := GetInstance()
fmt.Println(singleton.data)
}()
}
wg.Wait()
}
在上述代码中,GetInstance
函数使用sync.Once
来确保instance
仅在第一次调用GetInstance
时初始化。main
函数中启动了10个goroutine并发调用GetInstance
,无论有多少个goroutine并发调用,instance
只会被初始化一次。