如何实现并发安全的 map?
如何实现并发安全的 map?
提示
题眼: sync.Map 和基于互斥锁的 map 的区别
map 和其他基础数据结构一样,也存在并发安全问题。如果多个协程同时操作同一个 map,就可能出现冲突甚至致命错误。常见解决方式主要有两种。
最简单的方式是基于互斥锁实现并发安全的 map:
// SafeMap 定义一个结构体来表示并发安全的 map
type SafeMap struct {
mu sync.Mutex // 也可以优化为读写锁
data map[string]interface{}
}sync.Map 内部采用了读写分离的思路,大致可以理解为“只读区 + 脏数据区”,并配合原子操作与加锁来减少读路径上的竞争。它更适合读多写少、键比较稳定的场景。
重要
参考答案:
实现并发安全的 map,常见有两种方法。
第一种是自己封装一个 map,外面配 sync.Mutex 或 sync.RWMutex。这种方式实现简单,也最通用,适合绝大多数业务场景。如果读特别多、写比较少,可以考虑用读写锁来优化读性能。
第二种是使用 sync.Map。它是 Go 标准库提供的并发安全 map,内部不是单纯地给整个 map 粗暴加一把大锁,而是结合原子操作、只读结构和脏数据结构来优化并发访问。sync.Map 的优势是在某些读多写少、键集合相对稳定的场景下,能减少锁竞争;但它并不是所有场景都比普通 map + 锁 更好,所以大部分业务代码里,map + 锁 仍然是更常见、也更容易控制的选择。
