Once: una primitiva de concurrencia simple pero no simple

Once se puede usar para ejecutar una acción solo una vez y, a menudo, se usa en el escenario de inicialización de un objeto singleton.

Escenarios de uso de Once

sync.Once solo expone un método Do. Puede llamar al método Do varias veces, pero el parámetro f solo se ejecutará cuando se llame al método Do por primera vez. Aquí f es una función sin parámetros y sin valor de retorno.

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) // 无输出
}

Una vez se usa a menudo para inicializar recursos singleton, o acceso concurrente a recursos compartidos que solo necesitan inicializarse una vez, o para inicializar recursos de prueba una vez durante la prueba.

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()
}

Materiales de referencia:

Patrón singleton en golang

Supongo que te gusta

Origin blog.csdn.net/csdniter/article/details/111152388
Recomendado
Clasificación