Назад к вопросам
Middle
127
questionbank

Является ли структура данных map в Go безопасной?

Sobes Copilot

Получайте ответы в реальном времени

Ответ от нейросети

sobes.tech AI

Нет, стандартная map в Go не является потокобезопасной для конкурентного доступа на чтение и запись.

При попытке одновременной записи или комбинации чтения и записи из нескольких горутин в одну и ту же map без внешней синхронизации, возникнет race condition, что может привести к непредсказуемому поведению программы или панике.

Для обеспечения потокобезопасности при конкурентном доступе к map можно использовать:

  • sync.Mutex или sync.RWMutex для ручной блокировки.
  • sync.Map (введена в Go 1.9) для более специализированных сценариев, где частые записи и редко изменяющиеся элементы.

Пример использования sync.Mutex:

package main

import (
	"fmt"
	"sync"
)

type SafeMap struct {
	mu sync.Mutex
	m  map[string]int
}

func (sm *SafeMap) Add(key string, value int) {
	sm.mu.Lock() // Захватываем мьютекс перед записью
	defer sm.mu.Unlock() // Освобождаем мьютекс после завершения
	sm.m[key] = value
}

func (sm *SafeMap) Get(key string) (int, bool) {
	sm.mu.Lock() // Захватываем мьютекс перед чтением
	defer sm.mu.Unlock() // Освобождаем мьютекс после завершения
	val, ok := sm.m[key]
	return val, ok
}

func main() {
	sm := SafeMap{m: make(map[string]int)}

	var wg sync.WaitGroup
	go func() {
		wg.Add(1)
		defer wg.Done()
		sm.Add("ключа1", 1)
	}()
		go func() {
		wg.Add(1)
		defer wg.Done()
		sm.Add("ключ2", 2)
	}()

	wg.Wait()
	fmt.Println(sm.Get("ключа1")) // Безопасное чтение
}