为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
德玛西亚99 2022-05-18 10:12:16
我有一个在许多 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()}有没有一种安全的方法可以做到这一点?这几乎就像我想要一个竞争条件,我不介意它是否被多次写入,但是这样做的第一个线程应该阻止后续读取这样做。相当新的东西和一般的并发性。
查看完整描述

1 回答

?
开满天机

TA贡献1786条经验 获得超13个赞

在您的方法中,您必须先锁定,然后才能检查是否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

}


查看完整回答
反对 回复 2022-05-18
  • 1 回答
  • 0 关注
  • 109 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号