Go语言中什么是 sync.Once
Go语言中什么是 sync.Once
Once 可以用来执行且仅仅执行一次动作,常常用于单例对象的初始化场景。
Once 常常用来初始化单例资源,或者并发访问只需初始化一次的共享资 源,或者在测试的时候初始化一次测试资源。
sync.Once 只暴露了一个方法 Do,你可以多次调用 Do 方法,但是只有第 一次调用 Do 方法时 f 参数才会执行,这里的 f 是一个无参数无返回值 的函数。
1 回复
在Go语言中,sync.Once
是一个用于确保某个函数只被调用一次的同步原语。这对于初始化资源或执行只应运行一次的设置操作非常有用,尤其是在多线程环境中。使用 sync.Once
可以避免复杂的锁机制,同时确保初始化的安全性。
使用方式
sync.Once
类型有一个方法 Do(f func())
,这个方法接受一个无参数、无返回值的函数 f
。如果 Do
被多次调用,f
函数只会在第一次调用 Do
时被执行,后续的调用则不会执行 f
。
示例代码
package main
import (
"fmt"
"sync"
)
// 定义一个全局的sync.Once变量
var once sync.Once
// 定义一个初始化函数
func initDB() {
fmt.Println("Initializing database...")
// 这里可以放置数据库初始化的代码
}
func main() {
// 模拟多个goroutine尝试初始化数据库
var wg sync.WaitGroup
for i := 0; i < 5; i++ {
wg.Add(1)
go func() {
defer wg.Done()
// 使用once.Do来确保initDB只被调用一次
once.Do(initDB)
}()
}
wg.Wait()
fmt.Println("All goroutines have completed.")
}
// 输出结果:
// Initializing database...
// All goroutines have completed.
在上面的例子中,initDB
函数被设计为数据库的初始化函数,我们通过 sync.Once
的 Do
方法来确保不管有多少个goroutine尝试执行它,initDB
只会被执行一次。这在多线程环境中管理资源的初始化时非常有用。