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)
}

 

上一篇:从硬件角度窥探32位机上Hotspot如何实现volatile修饰的double,long原子性


下一篇:盘点Go中的开发神器