Middle
In what cases can thread safety when working with maps in Go be considered safe?
sobes.tech AI
Answer from AI
Thread safety when working with built-in maps in Go is guaranteed only under the following conditions:
- Read without writing to the same key. If multiple goroutines read from the map simultaneously, and none of them attempt to write or delete an element, then it is safe.
- Access only from one goroutine. If the map is used exclusively by one goroutine and is never passed or shared between others, then it is safe.
- Using
sync.Map. The specializedsync.Maptype from the Go standard library provides thread safety for concurrent read and write operations by multiple goroutines without the need for explicit mutexes.sync.Mapis optimized for cases where keys are read more often than they are written.
It is important to remember that simultaneous writing or deletion in a regular built-in map from different goroutines leads to a race condition (data race), which is undefined behavior and can cause panics or incorrect results.
To ensure thread safety during concurrent read and write operations on a built-in map, synchronization primitives such as sync.Mutex or sync.RWMutex should be used.
import (
"sync"
)
// Example of using sync.RWMutex for thread-safe regular map
type SafeMap struct {
mu sync.RWMutex
data map[string]int
}
func NewSafeMap() *SafeMap {
return &SafeMap{
data: make(map[string]int),
}
}
func (sm *SafeMap) Store(key string, value int) {
sm.mu.Lock() // Lock for writing
defer sm.mu.Unlock() // Unlock after completion
sm.data[key] = value
}
func (sm *SafeMap) Load(key string) (int, bool) {
sm.mu.RLock() // Lock for reading
defer sm.mu.RUnlock() // Unlock after reading
val, ok := sm.data[key]
return val, ok
}
Thus, a built-in map by itself is not thread-safe for all usage scenarios in a concurrent environment. Safety is achieved either by access restrictions (one goroutine or read-only), or by using sync.Map or manual synchronization.