MST

星途 面试题库

面试题:Go语言中sync.Once实现单例模式的原理

请简述在Go语言里,使用sync.Once实现单例模式的具体原理是什么?并给出一个简单的代码示例说明其用法。
48.5万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

原理

在Go语言中,sync.Once 实现单例模式的原理基于其内部的一个状态标志和一个互斥锁。当第一次调用 Once.Do(f) 时,Once 结构体中的状态标志会表明该操作尚未执行,此时互斥锁会被锁定,以确保只有一个 goroutine 能执行 f 函数。一旦 f 函数执行完毕,状态标志会被更新为已执行,后续再有调用 Once.Do(f) 时,由于状态标志已表明操作已执行,就不会再次执行 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
}

你可以在 main 函数中这样调用:

func main() {
    var wg sync.WaitGroup
    var instances []*Singleton
    for i := 0; i < 10; i++ {
        wg.Add(1)
        go func() {
            defer wg.Done()
            instance := GetInstance()
            instances = append(instances, instance)
        }()
    }
    wg.Wait()
    for _, inst := range instances {
        fmt.Println(inst)
    }
    // 这里所有的 inst 都是同一个实例
}