MST

星途 面试题库

面试题:Go语言中sync.Once在初始化中的常见应用场景

请阐述在Go语言里,sync.Once通常会在哪些初始化场景中使用,并举例说明。
27.0万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

sync.Once的使用场景

  1. 单例模式:在Go语言中没有传统面向对象语言那样的类和构造函数概念,sync.Once 可用于实现单例模式,保证某个资源只初始化一次。例如数据库连接池,避免多次初始化连接池带来资源浪费和不一致问题。
  2. 延迟初始化:对于一些初始化开销较大的资源,如加载配置文件、初始化复杂数据结构等,使用sync.Once可实现延迟初始化,只有在真正需要使用该资源时才进行初始化。

示例代码

package main

import (
    "fmt"
    "sync"
)

// Singleton结构体
type Singleton struct {
    data string
}

var instance *Singleton
var once sync.Once

// GetInstance获取单例实例
func GetInstance() *Singleton {
    once.Do(func() {
        instance = &Singleton{
            data: "initial data",
        }
    })
    return instance
}

在上述代码中,once.Do 确保 instance 只被初始化一次。无论多少个并发调用 GetInstance 函数,instance 只会在第一次调用 once.Do 时被初始化。 可以在 main 函数中测试:

func main() {
    var wg sync.WaitGroup
    for i := 0; i < 10; i++ {
        wg.Add(1)
        go func() {
            defer wg.Done()
            instance1 := GetInstance()
            fmt.Println(instance1)
        }()
    }
    wg.Wait()
}

此代码通过多个并发 goroutine 调用 GetInstance 函数,验证单例模式的正确性,每次输出的都是同一个 instance