Sobes.tech
Junior — Middle

Jakie są różnice między używaniem zwykłej mapy z blokadami a strukturą sync.Map do przechowywania danych?

sobes.tech AI

Odpowiedź od AI

Zwykła mapa (mapa) w Go nie jest bezpieczna dla wątków, dlatego przy jednoczesnym dostępie z wielu gorutyn konieczne jest użycie blokad (np. sync.Mutex lub sync.RWMutex) do ochrony danych. Wymaga to dodatkowego kodu i może prowadzić do blokad oraz obniżenia wydajności przy dużej konkurencji.

sync.Map to specjalistyczna, bezpieczna dla wątków struktura danych, zoptymalizowana pod kątem scenariuszy z częstymi operacjami odczytu i rzadkimi zapisami. Implementuje wewnętrzne mechanizmy synchronizacji i optymalizacji, pozwalając uniknąć jawnych blokad w kodzie.

Główne różnice:

  • Bezpieczeństwo wątków: sync.Map jest od początku bezpieczna dla wielu wątków, zwykła mapa nie.
  • Wydajność: sync.Map jest efektywna przy dużej liczbie równoległych odczytów i rzadkich zapisach; zwykła mapa z blokadami może być szybsza przy niskiej konkurencji.
  • API: sync.Map ma ograniczony zestaw metod (Load, Store, Delete, Range) i nie obsługuje bezpośredniego dostępu przez indeksowanie.

Przykład użycia sync.Map:

var m sync.Map
m.Store("key", "value")
if val, ok := m.Load("key"); ok {
    fmt.Println(val)
}

Jeśli potrzebujesz prostej mapy z kontrolą dostępu, możesz użyć map z sync.RWMutex:

var (
    mu sync.RWMutex
    m  = make(map[string]string)
)

// Zapis
mu.Lock()
m["key"] = "value"
mu.Unlock()

// Odczyt
mu.RLock()
val := m["key"]
mu.RUnlock()