在 Go语言 的并发编程中,我们经常会遇到这样的需求:某个初始化操作(比如配置加载、数据库连接、单例创建等)只需要在整个程序生命周期中执行一次,即使有多个 Goroutine 同时尝试执行它。这时候,sync.Once 就派上用场了!

sync.Once 是 Go 标准库 sync 包中的一个结构体,它提供了一种机制,确保某段代码在多线程(Goroutine)环境下仅被执行一次。它是 并发安全 的,无需额外加锁。
想象一下,你正在开发一个 Web 服务,需要在启动时加载配置文件。如果多个 Goroutine 同时启动并尝试加载配置,可能会导致:
使用 sync.Once 可以完美解决这些问题,确保初始化逻辑只运行一次。
使用 sync.Once 非常简单,只需两步:
sync.Once 类型的变量Do(func()) 方法,传入要只执行一次的函数下面是一个经典示例——实现 单例模式:
package mainimport ( "fmt" "sync")// Singleton 单例结构体type Singleton struct { data string}var ( instance *Singleton once sync.Once)// GetInstance 获取单例实例func GetInstance() *Singleton { once.Do(func() { fmt.Println("Creating singleton instance...") instance = &Singleton{data: "I am singleton!"} }) return instance}func main() { // 模拟多个 Goroutine 同时获取实例 var wg sync.WaitGroup for i := 0; i < 5; i++ { wg.Add(1) go func(id int) { defer wg.Done() s := GetInstance() fmt.Printf("Goroutine %d: %s\n", id, s.data) }(i) } wg.Wait()}运行结果(顺序可能不同,但“Creating singleton instance...”只打印一次):
Creating singleton instance...Goroutine 3: I am singleton!Goroutine 0: I am singleton!Goroutine 1: I am singleton!Goroutine 2: I am singleton!Goroutine 4: I am singleton!可以看到,尽管有 5 个 Goroutine 同时调用 GetInstance(),但初始化代码(once.Do 中的匿名函数)只执行了一次。这就是 sync.Once 的魔力!
Do 几乎无开销Do 不会重复执行函数除了实现 单例模式,sync.Once 还适用于:
1. sync.Once 不能重置。一旦执行过,就永远不会再执行。
2. 如果 Do 中的函数 panic,sync.Once 会认为“已执行”,后续调用不会再次执行。因此建议在函数内处理 panic。
once.Do(func() { defer func() { if r := recover(); r != nil { log.Printf("Recovering from panic in once.Do: %v", r) } }() // 可能 panic 的初始化代码})在 Go语言 开发中,sync.Once 是实现 并发安全 的“只执行一次”逻辑的最佳工具。它简洁、高效、可靠,特别适合用于 单例模式 和各种初始化场景。掌握它,能让你的并发程序更加健壮和高效!
记住这四个关键词:Go语言、sync.Once、单例模式、并发安全 —— 它们是你构建高性能 Go 应用的重要基石。
本文由主机测评网于2025-12-05发表在主机测评网_免费VPS_免费云服务器_免费独立服务器,如有疑问,请联系我们。
本文链接:https://www.vpshk.cn/2025123452.html