Map is not concurrently safe, when there are multiple concurrent groutines reading and writing the same map
Panic error will occur
concurrent map writes
For example, the following code will cause this error:
var mMap map[ int ] int func TestMyMap(t * testing.T) { mMap = make(map[ int ] int ) for i := 0 ; i < 5000 ; i++ { go func() { mMap[i] = i }() go readMap(i) } } func readMap(i int ) int { return mMap[i] }
There are many ways to solve this error. Now we take the way of read-write lock.
Concurrent access to the map is not safe, and undefined behavior will occur, causing the program to exit. Therefore, if you want to access the map concurrently in a multi-coroutine, you must provide a synchronization mechanism. Generally, the concurrent access control to the map is achieved through the read-write lock sync.RWMutex, and the map and sync.RWMutex can be encapsulated to achieve the map Secure concurrent access
Transformed code
type SMap struct { sync.RWMutex Map map[ int ] int } func (l *SMap) readMap(key int ) ( int , bool ) { l.RLock() value, ok: = l.Map[key] l.RUnlock() return value, ok } func (l *SMap) writeMap(key int , value int ) { l.Lock() l.Map[key] = value l.Unlock() } var mMap * SMap func TestMyMap(t * testing.T) { mMap = & SMap{ Map: make(map[ int ] int ), } for i := 0 ; i < 5000 ; i++ { go func() { mMap.writeMap(i, i) }() go readMap(i) } } func readMap(i int ) ( int , bool ) { return mMap.readMap(i) }
There are three ways:
1. Use channel
2. Use sync.map
3. Use map but must be locked