Ответ
Нет, стандартный тип map
в Go не является потокобезопасным. Одновременная запись и чтение из map
разными горутинами приведет к состоянию гонки (race condition), что может вызвать панику приложения или привести к непредсказуемым результатам.
Для обеспечения потокобезопасности при работе с map
используются следующие подходы:
-
sync.Mutex
илиsync.RWMutex
: Классический способ защиты с помощью мьютекса.RWMutex
предпочтительнее, когда количество чтений значительно превышает количество записей, так как он позволяет выполнять множество чтений одновременно.Пример с
sync.RWMutex
type SafeMap struct { mu sync.RWMutex m map[string]int } func (s *SafeMap) Get(key string) (int, bool) { s.mu.RLock() // Блокировка на чтение defer s.mu.RUnlock() val, ok := s.m[key] return val, ok } func (s *SafeMap) Set(key string, value int) { s.mu.Lock() // Блокировка на запись defer s.mu.Unlock() s.m[key] = value }
-
sync.Map
: Специализированный тип, добавленный в Go 1.9. Он оптимизирован для сценариев, где ключ после записи редко изменяется или удаляется, а количество чтений велико.sync.Map
позволяет избежать глобальной блокировки для большинства операций чтения, что делает его производительнееmap
с мьютексом в определенных условиях.