Thread-Safe Maps

In Go, maps are not safe for concurrent use. If one goroutine is writing to a map while another is reading from or writing to it, the program will crash with a fatal error: concurrent map writes.

The Problem

m := make(map[string]int)

// This will eventually crash if run on multiple cores
go func() { m["key"] = 1 }()
go func() { fmt.Println(m["key"]) }()

The Solution: Wrapping in a Struct

The standard way to make a map thread-safe is to wrap it in a struct along with a mutex.

type safeMap struct {
    mu   sync.Mutex
    data map[string]int
}

func (s *safeMap) Set(key string, val int) {
    s.mu.Lock()
    defer s.mu.Unlock()
    s.data[key] = val
}

func (s *safeMap) Get(key string) int {
    s.mu.Lock()
    defer s.mu.Unlock()
    return s.data[key]
}

By ensuring that every read and write operation is protected by the same mutex, you guarantee that only one goroutine touches the map at any given time.