美文网首页
golang 系列:sync.Once 讲解

golang 系列:sync.Once 讲解

作者: lincoln_hlf1 | 来源:发表于2021-08-16 23:31 被阅读0次

    sync.Once 介绍

    之前提到过 Go 的并发辅助对象:WaitGroup。同样的, sync.Once 也是 Go 官方的一并发辅助对象,它能够让函数方法只执行一次,达到类似 init 函数的效果。我们来看看它的简单用法:

    func main() {
        var once sync.Once
        onceFunc := func() {
            fmt.Println("Only once")
        }
    
        for i := 0; i < 10; i++ {
            once.Do(onceFunc)
        }
    }
    

    这里执行后我们将只看到一次 Only once 的打印信息,这就是 sync.Once 的一次性效果。

    sync.Once 源码

    我们来看下 sync.Once 的源码:

    type Once struct {
        done uint32
        m    Mutex
    }
    
    func (o *Once) Do(f func()) {
        // 原子加载标识值,判断是否已被执行过
        if atomic.LoadUint32(&o.done) == 0 {
            o.doSlow(f)
        }
    }
    
    func (o *Once) doSlow(f func()) { // 还没执行过函数
        o.m.Lock()
        defer o.m.Unlock()
        if o.done == 0 { // 再次判断下是否已被执行过函数
            defer atomic.StoreUint32(&o.done, 1) // 原子操作:修改标识值
            f() // 执行函数
        }
    }
    

    从上面可以分析出,sync.Once 是通过对一个标识值,原子性的修改和加载,来减少锁竞争的。


    感兴趣的朋友可以搜一搜公众号「 阅新技术 」,关注更多的推送文章。
    可以的话,就顺便点个赞、留个言、分享下,感谢各位支持!
    阅新技术,阅读更多的新知识。

    相关文章

      网友评论

          本文标题:golang 系列:sync.Once 讲解

          本文链接:https://www.haomeiwen.com/subject/ahfbbltx.html