Go 单例模式


为什么需要使用单例模式

type WebConfig struct {
    Port int
}

func GetConfig() *WebConfig {
    return &WebConfig{Port: 8080}
}

func main() {
    a := GetConfig()
    b := GetConfig()
    c := GetConfig()
    fmt.Println(a,b,c) // 明明是一样的配置,却开了 3 个地址存储
}

实现单例模式,方法一(单协程可用,多协程会导致并发不安全)

type WebConfig struct {
    Port int
}

var aConfig *WebConfig

func GetConfig() *WebConfig {
    if aConfig != nil { // 这样就保证了config统一性,还减少了内存的占用
        return aConfig
    }
    return &WebConfig{Port: 8080}
}

func main() {
    a := GetConfig()
    b := GetConfig()
    c := GetConfig()
    fmt.Println(a,b,c)
}

方法二(在方法一的基础上加锁)

var m sync.Mutex

func GetConfig() *WebConfig {
    m.Lock()
    defer m.Unlock()
    if aConfig != nil { // 这样就保证了config统一性,还减少了内存的占用
        return aConfig
    }
    return &WebConfig{Port: 8080}
}

方法三,使用Once(性能最高)

type WebConfig struct {
    Port int
}

var aConfig *WebConfig

var once sync.Once

func GetConfig() *WebConfig {
    once.Do(func() {
        aConfig = &WebConfig{Port: 8080}
    })
    return aConfig
}

func main() {
    a := GetConfig()
    b := GetConfig()
    c := GetConfig()
    fmt.Println(a,b,c)
}

相关