map不是并发安全的 , 当有多个并发的groutine读写同一个map时
会出现panic错误
concurrent map writes
例如下面的代码会出现这个错误:
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]
}
解决这个错误可以有多种方式 , 现在采取读写锁的方式 ,
并发访问map是不安全的,会出现未定义行为,导致程序退出。所以如果希望在多协程中并发访问map,必须提供某种同步机制,一般情况下通过读写锁sync.RWMutex实现对map的并发访问控制,将map和sync.RWMutex封装一下,可以实现对map的安全并发访问
改造后的代码
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)
}
有这三种方式:
1.使用channel
2.使用sync.map
3.使用map但必须进行加锁
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)