sync.Once и sync.Map
Однократная инициализация и конкурентные отображения
«sync.Once и sync.Map» — бесплатный урок Go Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Go Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Go Academy содержит 4 уроков всего.
sync.Once
sync.Once гарантирует, что функция будет выполнена ровно один раз, независимо от количества горутин, одновременно вызывающих её. Классический случай применения — отложенная инициализация одиночного объекта.
Once.Do
Только первый вызов Do выполняет функцию; последующие вызовы ничего не делают, даже если они выполняются из разных горутин.
var once sync.Once
var db *Database
func getDB() *Database {
once.Do(func() { db = openDB() })
return db
}Once не сбрасывается
После срабатывания sync.Once его нельзя сбросить. Если Вам нужно сбрасываемое однократное выполнение, вручную управляйте состоянием с помощью атомарной операции или мьютекса.
Поведение Once при панике
Если функция, переданная в Do, вызывает панику, Do считается выполненным, а последующие вызовы ничего не делают. Паника передаётся первому вызывающему.
Обзор sync.Map
sync.Map — это карта для конкурентного доступа, не требующая внешней блокировки. Она оптимизирована для двух шаблонов: (1) однократная запись и многократное чтение; (2) непересекающиеся наборы ключей для разных горутин.
Методы sync.Map
Основные методы: Store, Load, LoadOrStore, Delete, Range. Обобщённых параметров типов нет — ключи и значения имеют тип interface{}.
var m sync.Map
m.Store("key", 42)
v, ok := m.Load("key")
if ok { fmt.Println(v.(int)) }LoadOrStore
LoadOrStore возвращает существующее значение, если ключ найден, иначе сохраняет и возвращает новое значение. Логическое значение показывает, было ли значение загружено (true) или сохранено (false).
actual, loaded := m.LoadOrStore("key", "default")
if loaded { fmt.Println("existing:", actual) }Range
Range перебирает все пары «ключ — значение», вызывая функцию для каждой пары. Верните false, чтобы остановить перебор.
m.Range(func(k, v any) bool {
fmt.Println(k, v)
return true // continue
})Когда использовать sync.Map
В большинстве случаев предпочтительнее обычная карта с мьютексом — она проще и зачастую быстрее. Используйте sync.Map, если профилирование показывает конкуренцию или шаблон доступа соответствует целевым сценариям её оптимизации.
LoadAndDelete
LoadAndDelete атомарно загружает значение и удаляет ключ, возвращая предыдущее значение и признак его наличия.
v, loaded := m.LoadAndDelete("key")
if loaded { fmt.Println("deleted:", v) }sync.Map не является обобщённой
Значения, сохранённые в sync.Map, имеют тип any. Оберните sync.Map в типизированную структуру с типобезопасными методами, чтобы избежать разбросанных по кодовой базе проверок типов.
Быстрая проверка
Что гарантирует sync.Once?
Повторение: sync.Once и sync.Map
Основные моменты:
- sync.Once: выполняет функцию ровно один раз; сброс невозможен
- sync.Map: конкурентная карта, оптимизированная для сценариев с преобладанием чтения или с непересекающимися ключами
- Для безопасности используйте типизированные оболочки вокруг sync.Map
Часто задаваемые вопросы
Урок «sync.Once и sync.Map» бесплатный?
Да — полный текст урока «sync.Once и sync.Map» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Go Academy, подпишись на CoddyKit PRO. Курс Go Academy содержит 4 уроков всего.
Чему я научусь в уроке «sync.Once и sync.Map»?
Однократная инициализация и конкурентные отображения Ты практикуешь Go Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Go Academy?
Предыдущий опыт не требуется. Go Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.
Сколько времени занимает урок «sync.Once и sync.Map»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Go Academy?
Да. Каждый урок Go Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- sync.Mutex и sync.RWMutex
- sync.WaitGroup
- sync.Once и sync.Map
- Детектор состязаний и безопасные шаблоны