map不是并发安全的 , 当有多个并发的groutine读写同一个map时
会出现panic错误
concurrent map writes
例如下面的代码会出现这个错误:
var mMap map[int]intfunc 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]
}
解决这个错误可以有多种方式 , 现在采取读写锁的方式 ,
并发访问map是不安全的,会出现未定义行为,导致程序退出。所以如果希望在多协程中并发访问map,必须提供某种同步机制,一般情况下通过读写锁sync.RWMutex实现对map的并发访问控制,将map和sync.RWMutex封装一下,可以实现对map的安全并发访问
改造后的代码
type SMap struct {sync.RWMutexMap 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] = valuel.Unlock()
}var mMap *SMapfunc 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)
}
有这三种方式:
1.使用channel
2.使用sync.map
3.使用map但必须进行加锁