MST

星途 面试题库

面试题:Go语言中sync.Once方法的使用场景及原理

请阐述在Go语言中,sync.Once方法一般适用于哪些场景?它是如何确保初始化的安全性的?可以结合简单代码示例说明。
11.3万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

sync.Once适用场景

  1. 单例模式:在Go语言中实现单例模式,确保某个实例只被创建一次。
  2. 资源初始化:对于一些需要初始化且只初始化一次的资源,如数据库连接池、配置文件加载等,使用sync.Once可以保证初始化的唯一性。

确保初始化安全性的原理

sync.Once内部包含一个done标志位和一个互斥锁mu。第一次调用Do方法时,done为0,互斥锁会被锁定,执行传入的函数f,执行完毕后将done置为1。后续再次调用Do方法时,由于done已经为1,不会再执行f,从而保证了初始化的安全性。

代码示例

package main

import (
    "fmt"
    "sync"
)

type Singleton struct {
    data string
}

var instance *Singleton
var once sync.Once

func GetInstance() *Singleton {
    once.Do(func() {
        instance = &Singleton{
            data: "Initial data",
        }
    })
    return instance
}

func main() {
    var wg sync.WaitGroup
    var instances []*Singleton
    for i := 0; i < 10; i++ {
        wg.Add(1)
        go func() {
            defer wg.Done()
            inst := GetInstance()
            instances = append(instances, inst)
        }()
    }
    wg.Wait()

    for i, inst := range instances {
        fmt.Printf("Instance %d: %p\n", i, inst)
    }
}

在上述代码中,GetInstance函数使用sync.Once确保instance只被初始化一次。即使多个goroutine同时调用GetInstance,也只会创建一个Singleton实例。通过打印实例的地址可以验证这一点。