Ответ
sync.Once
гарантирует, что определенный код выполнится ровно один раз, даже если его вызывают из нескольких горутин. Это полезно для ленивой инициализации или однократного выполнения ресурсоемких операций.
Пример:
var (
once sync.Once
config map[string]string
)
func loadConfig() {
once.Do(func() {
// Этот код выполнится только один раз, независимо от количества вызовов loadConfig
config = readConfigFromFile()
})
}
// Вспомогательная функция для примера
func readConfigFromFile() map[string]string {
// Имитация чтения конфигурации
return map[string]string{"key": "value"}
}
Ключевые особенности:
- Потокобезопасность: Гарантирует корректное выполнение в конкурентной среде.
- Однократное выполнение: Функция, переданная в
Do
, будет вызвана только один раз за всё время жизни программы. - Игнорирование последующих вызовов: После первого успешного выполнения
Do
, все последующие вызовыonce.Do
не будут выполнять переданную функцию, но будут ждать завершения первого выполнения, если оно еще не закончено. - Применение: Идеально подходит для инициализации синглтонов, загрузки конфигураций, установки соединений с базами данных или других операций, которые должны произойти ровно один раз.
sync.Once
является фундаментальным примитивом для обеспечения корректной и эффективной инициализации в конкурентных Go-приложениях.