我想用go语言实现单例,普通单例之间的区别在于实例是map结构中具有不同键的单例。像这样的代码。我不确定演示代码是否会引起任何数据争用。任何帮助。谢谢
var instanceLock sync.Mutex
var instances map[string]string
func getDemoInstance(key string) string {
if value, ok := instances[key]; ok {
return value
}
instanceLock.Lock()
defer instanceLock.Unlock()
if value, ok := instances[key]; ok {
return value
} else {
instances[key] = key + key
return key + key
}
}
是,有数据争用,您可以通过用go run -race main.go
运行来确认。如果一个goroutine锁定并修改了地图,则另一个goroutine可能在锁定之前正在读取它。
您可以在仅阅读sync.RWMutex
时使用它进行锁定(允许多个阅读器,而不会互相阻塞)。>>
例如:
sync.RWMutex
您也可以尝试:var (
instancesMU sync.RWMutex
instances = map[string]string{}
)
func getDemoInstance(key string) string {
instancesMU.RLock()
if value, ok := instances[key]; ok {
instancesMU.RUnlock()
return value
}
instancesMU.RUnlock()
instancesMU.Lock()
defer instancesMU.Unlock()
if value, ok := instances[key]; ok {
return value
}
value := key + key
instances[key] = value
return value
}