РЕПЕТИТОР математика физика информатика
Для школьников и студентов. Подтягивание пробелов. ЦЭ, ЦТ, ОГЭ, ЕГЭ.
Идет набор на ЛЕТО. Жмите для подробностей:)
848 of 1593 menu

Метод sync.Once.Do

Метод sync.Once.Do принимает в качестве аргумента функцию без параметров и возвращаемых значений. Он гарантирует, что эта функция будет вызвана только один раз, независимо от количества горутин, которые одновременно вызывают Do на одном и том же экземпляре sync.Once. Если функция вызывается повторно, Do ничего не делает и возвращает управление. Это идеальный механизм для ленивой инициализации объектов, загрузки конфигураций или создания синглтонов.

Синтаксис

var once sync.Once once.Do(func() { // код, который должен выполниться один раз })

Базовый пример

В этом примере sync.Once.Do используется для инициализации глобальной переменной. Несмотря на то, что мы запускаем несколько горутин, инициализация произойдет только один раз.

package main import ( "fmt" "sync" ) var ( config string once sync.Once ) func loadConfig() { config = "config loaded" fmt.Println("Config loaded once") } func main() { var wg sync.WaitGroup for i := 0; i < 5; i++ { wg.Add(1) go func() { defer wg.Done() once.Do(loadConfig) fmt.Println("Config:", config) }() } wg.Wait() }

Результат выполнения кода (порядок строк может отличаться, но сообщение о загрузке появится только один раз):

"Config loaded once" "Config: config loaded" "Config: config loaded" "Config: config loaded" "Config: config loaded" "Config: config loaded"

Пример с паникой

Важно: если функция, переданная в Do, вызывает панику, то Once считает, что вызов не был завершен успешно, и при следующем вызове Do выполнит функцию снова. Это поведение позволяет восстановиться после ошибок инициализации.

package main import ( "fmt" "sync" ) func main() { var once sync.Once counter := 0 for i := 0; i < 3; i++ { func() { defer func() { if r := recover(); r != nil { fmt.Println("recovered from:", r) } }() once.Do(func() { counter++ fmt.Println("attempt:", counter) if counter == 1 { panic("initialization failed") } }) }() } fmt.Println("final counter:", counter) }

Результат выполнения кода:

"attempt: 1" "recovered from: initialization failed" "attempt: 2" "final counter: 2"

Смотрите также

  • тип sync.Once,
    который предоставляет механизм однократного выполнения
  • тип sync.WaitGroup,
    который используется для ожидания завершения горутин
  • тип sync.Mutex,
    который обеспечивает взаимное исключение при доступе к данным
  • тип sync.RWMutex,
    который предоставляет блокировку с разделяемым доступом на чтение
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить