Golang Map并发安全
在Golang中,当多个goroutine同时读写同一个map时会出现并发安全问题吗?如果需要保证map的并发安全,有哪些常用的解决方案?sync.Map和加锁(map+Mutex)哪种方式性能更好,各自适合什么场景?在处理高并发读写时有哪些最佳实践需要注意?
2 回复
Golang的map在并发读写时非线程安全,可能导致panic。建议使用sync.Map或结合sync.RWMutex实现并发安全。在高并发读少写多场景下,sync.Map性能更优。
更多关于Golang Map并发安全的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
在Go语言中,标准的map类型不是并发安全的。当多个goroutine同时对同一个map进行读写操作时,可能导致数据竞争(data race)和运行时panic。
解决方案
1. 使用互斥锁(sync.Mutex / sync.RWMutex)
通过互斥锁保护map的并发访问:
package main
import (
"sync"
)
type SafeMap struct {
mu sync.RWMutex
m map[string]int
}
func NewSafeMap() *SafeMap {
return &SafeMap{
m: make(map[string]int),
}
}
func (s *SafeMap) Set(key string, value int) {
s.mu.Lock()
defer s.mu.Unlock()
s.m[key] = value
}
func (s *SafeMap) Get(key string) (int, bool) {
s.mu.RLock()
defer s.mu.RUnlock()
val, ok := s.m[key]
return val, ok
}
func (s *SafeMap) Delete(key string) {
s.mu.Lock()
defer s.mu.Unlock()
delete(s.m, key)
}
2. 使用sync.Map
Go 1.9+ 提供了并发安全的sync.Map,适用于读多写少的场景:
package main
import (
"sync"
)
func main() {
var sm sync.Map
// 存储键值对
sm.Store("key1", 100)
sm.Store("key2", 200)
// 读取
if val, ok := sm.Load("key1"); ok {
println(val.(int)) // 输出: 100
}
// 删除
sm.Delete("key2")
// 遍历所有键值
sm.Range(func(key, value interface{}) bool {
println(key.(string), value.(int))
return true // 继续遍历
})
}
选择建议
- 互斥锁方案:适用于需要复杂操作或一致性要求高的场景。
- sync.Map:适用于读多写少、不需要复杂事务的场景,性能更好。
注意:并发编程时务必通过go run -race进行数据竞争检测。

