Once:一个简约而不简单的并发原语

Once 可以用来执行且仅仅执行一次动作,常常用于单例对象的初始化场景。

Once 的使用场景

sync.Once 只暴露了一个方法 Do,你可以多次调用 Do 方法,但是只有第一次调用 Do 方法时 f 参数才会执行,这里的 f 是一个无参数无返回值的函数

func main() {
    
    
    var once sync.Once

    // 第一个初始化函数
    f1 := func() {
    
    
        fmt.Println("in f1")
    }
    once.Do(f1) // 打印出 in f1

    // 第二个初始化函数
    f2 := func() {
    
    
        fmt.Println("in f2")
    }
    once.Do(f2) // 无输出
}

Once 常常用来初始化单例资源,或者并发访问只需初始化一次的共享资源,或者在测试的时候初始化一次测试资源。

syncOnce.go

package main

import (
    "fmt"
    "sync"
)

var once sync.Once

type single struct {
    
    
}

var singleInstance *single

func getInstance() *single {
    
    
    if singleInstance == nil {
    
    
        once.Do(
            func() {
    
    
                fmt.Println("Creating single instance now.")
                singleInstance = &single{
    
    }
            })
    } else {
    
    
        fmt.Println("Single instance already created.")
    }

    return singleInstance
}

main.go

package main

import (
    "fmt"
)

func main() {
    
    

    for i := 0; i < 30; i++ {
    
    
        go getInstance()
    }

    // Scanln is similar to Scan, but stops scanning at a newline and
    // after the final item there must be a newline or EOF.
    fmt.Scanln()
}

参考资料:

golang中的单例模式

猜你喜欢

转载自blog.csdn.net/csdniter/article/details/111152388