sync.Once

作者: 申_9a33 | 来源:发表于2021-08-02 15:51 被阅读0次

    sync.Once 的使用场景

    sync.Once 是 Go 标准库提供的使函数只执行一次的实现,常应用于单例模式,例如初始化配置、保持数据库连接等。作用与 init 函数类似,但有区别。

    1.init 函数是当所在的 package 首次被加载时执行,若迟迟未被使用,则既浪费了内存,又延长了程序加载时间。

    2.sync.Once 可以在代码的任意位置初始化和调用,因此可以延迟到使用时再执行,并发场景下是线程安全的。

    3.在多数情况下,sync.Once 被用于控制变量的初始化,这个变量的读写满足如下三个条件:

    • 当且仅当第一次访问某个变量时,进行初始化(写);
    • 变量初始化过程中,所有读都被阻塞,直到初始化完成;
    • 变量仅初始化一次,初始化完成后驻留在内存里。
    • sync.Once 仅提供了一个方法 Do,参数 f 是对象初始化函数。

    示例

    package main
    
    import (
        "log"
        "os"
        "strconv"
        "sync"
        "time"
    )
    
    type Config struct {
        Server string
        Port   int64
    }
    
    var (
        once   sync.Once
        config *Config
    )
    
    func ReadConfig() *Config {
        once.Do(func() {
            var err error
            config = &Config{Server: os.Getenv("TT_SERVER_URL")}
            config.Port, err = strconv.ParseInt(os.Getenv("TT_PORT"), 10, 0)
            if err != nil {
                config.Port = 8080 // default port
            }
            log.Println("init config")
        })
        return config
    }
    
    func main() {
        for i := 0; i < 10; i++ {
            go func() {
                _ = ReadConfig()
            }()
        }
        time.Sleep(time.Second)
    }
    
    

    输出:2021/08/02 15:49:46 init config

    相关文章

      网友评论

          本文标题:sync.Once

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