zoukankan      html  css  js  c++  java
  • golang sync.Once用法

    sync.Once能确保实例化对象Do方法在多线程环境只运行一次,内部通过互斥锁实现

    Do方法

    Once类型的Do方法只接收一个参数,参数的类型必须是func(),即无参数无返回的函数。该方法的功能并不是对每一种参数函数都只执行一次,而是只执行首次被调用时传入的那个函数,并且之后不会再执行任何参数函数。所以,如果有多个需要执行一次的函数,应该为它们每一个都分配一个sync.Once类型的值。

    var once sync.Once
        for i, v := range make([]string, 10) {
            once.Do(func() {
                t.Log("function 1")
            })
        }
        for i := 0; i < 10; i++ {
            once.Do(func() {
                t.Log("function 2")
            })
        }

    这段示例代码只会输出一次“function 1”

    与init函数对比

    sync.Once 是 Golang package 中使方法只执行一次的对象实现,作用与 init 函数类似。但也有所不同。

    • init 函数是在文件包首次被加载的时候执行,且只执行一次
    • sync.Onc 是在代码运行中需要的时候执行,且只执行一次

    当一个函数不希望程序在一开始的时候就被执行的时候,我们可以使用 sync.Once 。

    源码

    sync.Once 使用变量 done 来记录函数的执行状态,使用 sync.Mutex 和 sync.atomic 来保证线程安全的读取 done 。

    func (o *Once) Do(f func()) {
        if atomic.LoadUint32(&o.done) == 0 {
            // Outlined slow-path to allow inlining of the fast-path.
            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()
        }
    }

    实现中也用到了类似double check思想

  • 相关阅读:
    C语言指针强制类型转换
    iphone开发实现单选框
    深入研究java.lang.Runtime类
    hoj 1760 The jackpot一维
    人生最有趣味的事
    GAE 博客——B3log Solo 0.3.0 正式版发布了!
    “三国演义”何处去
    boost库中的智能指针向上转换
    GAE 博客——B3log Solo 0.3.5 正式版发布了!
    GAE 博客——B3log Solo 0.3.0 正式版发布了!
  • 原文地址:https://www.cnblogs.com/luoming1224/p/14713998.html
Copyright © 2011-2022 走看看