使用sync.Once实现Go语言线程安全单例,确保多协程下仅初始化一次,避免竞态条件,代码简洁可靠。

在Go语言中,单例模式常用于确保某个类型在整个程序生命周期中仅存在一个实例,比如配置管理、数据库连接池等场景。实现线程安全的单例模式,sync.Once 是最推荐的方式,它能保证初始化操作只执行一次,且在多协程环境下安全可靠。
多协程环境下,多个 goroutine 同时调用单例获取实例时,可能造成多次初始化。传统加锁方式虽然可行,但代码复杂且容易出错。Go 标准库中的 sync.Once 提供了简洁高效的解决方案。
以下是基于 sync.Once 的典型实现方式:
package singleton
import (
"sync"
)
// 单例结构体
type Singleton struct {
Data string
}
var (
instance *Singleton
once sync.Once
)
// GetInstance 返回单例实例,线程安全
func GetInstance() *Singleton {
once.Do(func() {
instance = &Singleton{
Data: "initialized",
}
})
return instance
}
关键点说明:
立即学习“go语言免费学习笔记(深入)”;
可以通过启动多个 goroutine 来验证单例是否真正唯一:
package main
import (
"fmt"
"sync"
"your-package/singleton"
)
func main() {
var wg sync.WaitGroup
for i := 0; i < 10; i++ {
wg.Add(1)
go func() {
defer wg.Done()
obj := singleton.GetInstance()
fmt.Printf("Instance address: %p\n", obj)
}()
}
wg.Wait()
}
输出结果中所有地址都相同,说明无论多少协程调用,实例始终唯一。
这种实现是懒加载的——实例在第一次调用 GetInstance() 时才创建,避免程序启动时不必要的开销。同时,sync.Once 内部做了优化,一旦初始化完成,后续调用几乎无额外开销。
基本上就这些。用 sync.Once 写单例,简单、安全、高效,是Go中最推荐的做法。
以上就是Golang单例模式实现 sync.Once线程安全方案的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号