为什么需要使用单例模式
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) }