go - 如何实现单例

标签 go singleton instance

我想用 Go 实现一个单例。普通单例的区别在于实例是单例,在映射结构中具有不同的键。像这样的代码。我不确定演示代码是否存在任何数据竞争。

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 读取时锁定(允许多个读取器互不阻塞)。

例如:

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
}

关于go - 如何实现单例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62260512/

相关文章:

java - 让接口(interface)提供实现它的类的实例

c++ - 如何使用 boost::call_once 在 Linux 上用 C++ 设计单例类?

javascript - 引用 JS 对象中的内部变量

java - Guava 映射将类实例存储为键和 int 值

xml - golang中如何将编码为UTF-16的xml转换为UTF-8

regex - 转义字符串特殊字符以在 golang 正则表达式中使用

c# - 静态到实例,我该如何正确处理?

c++ - 静态函数接收到错误的参数

go - 如何使用 golang 和 labstack echo 处理对多个服务的代理

mongodb - 无法从 Mongo 记录 [mgo] :golang 的结构接口(interface)上仅更新一个值