Go 并发安全 Map 三种实现对比:从互斥锁到分段锁 实验环境:Go 1.24, Apple M4, macOS 15, 10 核 CPU 所有测试均通过 go test -race 竞态检测,零数据竞争。 目录 问题背景 解法一:sync.RWMutex 解法二:sync.Map 解法三:分段锁 ShardMap 测试策略与用例 Benchmark 性能对比 分片均匀性验证 竞态检测 如何选择 完整源码 问题背景 Go 原生的 map 不是并发安全的。多个 goroutine 同时读写同一个 map 会触发 race condition,轻则数据错乱,重则 fatal error: concurrent map read and map write 直接崩溃。 Go 中实现并发安全 map 有三种主流方案,各有优劣。我把三种都写了一遍,用同一套测试跑了一下,记录一下结果。 解法一:sync.RWMutex 思路 最传统、最稳妥的做法。用一个 sync.RWMutex 保护整个 map: 读操作:加 RLock()(读锁之间不互斥) 写操作:加 Lock()(独占) 实现 type RWMutexMap struct { mu sync.RWMutex data map[string]int } func NewRWMutexMap() *RWMutexMap { return &RWMutexMap{data: make(map[string]int)} } func (m *RWMutexMap) Get(key string) (int, bool) { m.mu.RLock() // 读锁:允许多个 goroutine 同时持有 defer m.mu.RUnlock() v, ok := m.data[key] return v, ok } func (m *RWMutexMap) Set(key string, val int) { m.mu.Lock() // 写锁:独占 defer m.mu.Unlock() m.data[key] = val } func (m *RWMutexMap) Delete(key string) { m.mu.Lock() defer m.mu.Unlock() delete(m.data, key) } 优点 实现简单,代码量最小 逻辑直观,容易理解和维护 RWMutex 在读多写少场景下性能可接受 缺点 只有一把全局锁,所有写操作串行化 高并发写入时,锁竞争成为瓶颈 读写锁本身有开销 解法二:sync.Map 思路 Go 标准库 sync 包内置的并发安全 map。接口是 any 类型的(无泛型),我们封装一层提供类型安全。 ...
My 1st post
Hello Hugo