Логотип YeaHub

База вопросов

Собеседования

Тренажёр

База ресурсов

Обучение

Навыки

Задачи

Войти

Выбери, каким будет IT завтра — вместе c нами!

YeaHub — это полностью открытый проект, призванный объединить и улучшить IT-сферу. Наш исходный код доступен для просмотра на GitHub. Дизайн проекта также открыт для ознакомления в Figma.

© 2026 YeaHub

AI info

Карта сайта

Документы

Медиа

Назад
Вопрос про Golang: sync.Once, goroutine, lazy initialization, singleton, concurrency

Как работает sync.Once и в каких сценариях его применяют?

Вопрос проверяет понимание механизма однократного выполнения в Go и его применения для ленивой инициализации и гарантии однократного выполнения кода.

Короткий ответ

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

Длинный ответ

Что такое sync.Once?

sync.Once — это примитив синхронизации из стандартной библиотеки Go, который гарантирует, что переданная функция будет выполнена ровно один раз, независимо от количества вызовов метода Do() из разных горутин. Он идеально подходит для ленивой инициализации (lazy initialization) и создания синглтонов.

Как он работает?

sync.Once использует внутренний мьютекс и атомарный флаг. При первом вызове Do() он блокирует мьютекс, проверяет флаг, и если функция еще не выполнялась, запускает её. После завершения флаг устанавливается, и последующие вызовы Do() сразу возвращаются, не выполняя функцию.

Пример кода

package main

import (
    "fmt"
    "sync"
)

var once sync.Once
var config map[string]string

func loadConfig() {
    fmt.Println("Loading config...")
    config = map[string]string{"key": "value"}
}

func getConfig() map[string]string {
    once.Do(loadConfig)
    return config
}

func main() {
    var wg sync.WaitGroup
    for i := 0; i < 10; i++ {
        wg.Add(1)
        go func() {
            defer wg.Done()
            fmt.Println(getConfig())
        }()
    }
    wg.Wait()
}

В этом примере loadConfig() выполнится только один раз, даже если getConfig() вызывается из 10 горутин одновременно.

Где применяется?

  • Ленивая инициализация: загрузка конфигурации, подключение к базе данных, инициализация логгера.
  • Синглтоны: гарантия единственного экземпляра объекта.
  • Однократная настройка: регистрация драйверов, инициализация глобальных переменных.

Вывод

sync.Once — простой и эффективный инструмент для гарантии однократного выполнения кода в многопоточной среде. Его стоит применять везде, где требуется ленивая инициализация или создание синглтонов с потокобезопасностью.

  • Аватар

    Golang Guru

    Maxim Lukyanov

    Guru – это эксперты YeaHub, которые помогают развивать комьюнити.

Уровень

  • Рейтинг:

    4

  • Сложность:

    5

Навыки

  • Golang

    Golang

Ключевые слова

#sync.Once

#goroutine

#lazy initialization

#singleton

#concurrency

Подпишись на Golang Developer в телеграм

  • Аватар

    Golang Guru

    Maxim Lukyanov

    Guru – это эксперты YeaHub, которые помогают развивать комьюнити.