sync.Once的作用正是为了防止在多goroutine并发执行时,对某个操作进行重复的初始化。它确保即使在高度并发的场景下,某些高成本的初始化操作(比如创建资源、加载配置、设置全局状态等)也只会被执行一次。
比如进行下面的这个例子,建立数据库连接:
var (db *sql.DBonce sync.OncedbDial = func() (*sql.DB, error) {dsn := "user:password@tcp(localhost:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"return sql.Open("mysql", dsn)}
)func GetDB(ctx context.Context) (*sql.DB, error) {var err erroronce.Do(func() {db, err = dbDial()if err != nil {log.Fatalf("Failed to establish database connection: %v", err)}// 检查连接是否有效并设置适当的重试策略或超时if err = db.PingContext(ctx); err != nil {log.Fatalf("Failed to ping the database: %v", err)}})return db, err
}