猿问

是否可以在不触发竞争条件的情况下检查字段是否已设置?

我有一个在许多 goroutine 之间共享的结构,如果可能的话,我想减少计算结构上一个字段的次数。可能更容易显示:


type Container struct {

    Items []Item

    mu    sync.RWMutex

}


(container *Container) func loadContainer() {

    if container.Items != nil { // This is detected as a race condition by go

        return 

    }

    container.mu.Lock()

    container.Items = loadItems() // Does some logic that I would like to avoid repeating

    container.mu.Unlock()

}

有没有一种安全的方法可以做到这一点?这几乎就像我想要一个竞争条件,我不介意它是否被多次写入,但是这样做的第一个线程应该阻止后续读取这样做。相当新的东西和一般的并发性。


德玛西亚99
浏览 110回答 1
1回答

开满天机

在您的方法中,您必须先锁定,然后才能检查是否Items已设置。例如:func (container *Container) loadContainer() {    container.mu.Lock()    defer container.mu.Unlock()    if container.Items != nil {        return    }    container.Items = loadItems()}但sync.Once提供了更好更快的替代方案。隐藏该字段也是明智之举,Items以免被意外引用。导出的函数应该负责初始化,并返回值,只初始化一次:type Container struct {    once  sync.Once    items []Item}func (container *Container) GetItems() []Item {    container.once.Do(func() {        container.Items = loadItems()    })    return container.items}
随时随地看视频慕课网APP

相关分类

Go
我要回答