MST

星途 面试题库

面试题:Go中sync.Once实现单例模式的细节

使用sync.Once在Go语言中实现一个单例模式,要求考虑到并发安全、懒加载以及资源释放等方面,并解释代码中每个关键步骤的作用。
23.7万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试
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: "初始化的数据",
        }
        defer func() {
            // 这里假设当单例对象不再使用时,可能需要释放一些资源,比如关闭文件描述符等
            // 实际应用中根据具体需求编写资源释放代码
            fmt.Println("资源释放逻辑(示例)")
        }()
    })
    return instance
}

关键步骤解释:

  1. 定义Singleton结构体:用于表示单例对象,在这个结构体中可以定义单例对象所需要的各种属性和方法,这里定义了一个data字符串属性作为示例。
  2. 定义全局变量
    • instance:用于存储单例实例,初始值为nil,体现懒加载特性,只有在第一次调用GetInstance时才会初始化。
    • oncesync.Once类型变量,Go语言提供的用于确保某段代码只执行一次的工具,在并发环境下保证单例实例的唯一性。
  3. GetInstance函数
    • once.Do(func())once.Do方法接受一个函数作为参数,这个函数内的代码只会被执行一次,无论有多少个并发调用GetInstance
    • Do方法传入的函数中,初始化instanceSingleton结构体实例,并赋予data初始值,完成单例对象的创建。
    • defer语句:在instance初始化完成后,使用defer关键字定义一个匿名函数,该函数用于处理资源释放逻辑。虽然这里只是打印了一个示例信息,实际应用中可根据具体资源类型编写对应的释放代码,如关闭数据库连接、文件句柄等。最后返回instance,使得调用者可以获取到单例实例。这样就通过sync.Once实现了一个并发安全、懒加载且考虑资源释放的单例模式。