Map is not concurrency safe, when there are multiple concurrent growths reading and writing the same map
A panic error occurs
concurrent map writes
For example, this error occurs in the following code:
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 problem. Now we use read-write lock,
Concurrent access to map is not safe, and undefined behavior will appear, leading to program exit. Therefore, if you want to access the map concurrently in multiple coroutines, you must provide some synchronization mechanism. Generally, you can control the concurrent access to the map by reading and writing the lock sync.rwmutex. Encapsulating the map and sync.rwmutex can realize the secure concurrent access to the map
Code after transformation
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 lock it