Как работает sync.Once?

Middle
1.1k просмотров
AFK Offer AI

sync.Once гарантирует, что функция выполнится ровно один раз, даже при вызове из нескольких горутин. Классика — ленивая инициализация.

var (
    instance *Database
    once     sync.Once
)

func GetDB() *Database { once.Do(func() { instance = connectToDB() // выполнится 1 раз }) return instance }

Ключевые свойства:

  • Потокобезопасна
  • Если f паникует — Once считается выполненной (повторный вызов НЕ ретраит)
  • Все горутины, вызвавшие Do параллельно, блокируются пока первая не завершит f
С Go 1.21 появились sync.OnceFunc, sync.OnceValue, sync.OnceValues:

getConfig := sync.OnceValue(func() *Config {
    return loadConfig() // вызовется 1 раз, результат кешируется
})
cfg := getConfig()
Следующий вопрос

Что будет если закрыть уже закрытый канал?