MST

星途 面试题库

面试题:Go语言中sync.Once如何实现单例模式的延迟初始化

在Go语言中,使用sync.Once实现单例模式时,简述延迟初始化的具体实现机制。请举例说明如何通过sync.Once确保某个资源仅在第一次使用时初始化,并且后续调用不会重复初始化。
35.9万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试
  1. 延迟初始化的具体实现机制
    • sync.Once类型只有一个方法Do,其签名为func (o *Once) Do(f func())
    • 当第一次调用Do方法时,它会执行传入的函数f,这个函数f负责初始化资源。sync.Once内部通过一个done标志和一个互斥锁mu来实现这个机制。第一次调用Do时,donefalse,互斥锁mu确保只有一个goroutine能进入临界区执行f,执行完f后,done被设置为true。后续调用Do时,若donetrue,则直接返回,不会再执行f,从而实现延迟初始化且仅初始化一次。
  2. 示例代码
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
    numGoroutines := 10
    for i := 0; i < numGoroutines; i++ {
        wg.Add(1)
        go func() {
            defer wg.Done()
            singleton := GetInstance()
            fmt.Println(singleton.data)
        }()
    }
    wg.Wait()
}

在上述代码中,GetInstance函数使用sync.Once来确保instance仅在第一次调用GetInstance时初始化。main函数中启动了10个goroutine并发调用GetInstance,无论有多少个goroutine并发调用,instance只会被初始化一次。