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思想

  • 相关阅读:
    埋点功能测试
    jmeter提取A接口返回值传入B接口
    css(2)---倒角阴影 框模型
    css(1)
    node 练习
    学习过程中遇到的问题及解决方法
    node.js(5)——mysql、连接池
    node.js(4)——中间件
    node.js(3)——express
    node.js(2)
  • 原文地址:https://www.cnblogs.com/luoming1224/p/14713998.html
Copyright © 2011-2022 走看看