直接回答:sync.Map 用两个 map 做读写分离:只读的 read(atomic.Value 持有,可无锁读)和加锁访问的 dirty。读先查 read;未命中且 amended 标记为真才加锁查 dirty,并给 misses +1;misses 达到 dirty 长度时把 dirty 整体提升为新 read。写入时若 key 已在 read 中且未被标记删除,直接 CAS 更新 entry 指针、不碰锁;否则走 dirty 加锁路径,dirty 为 nil 时还要从 read 复制未删除项重建。
展开解析:收益在读路径大部分时间无锁。适合两类场景:读远多于写(配置表、缓存元数据),或各 goroutine 操作不相交的 key 集合。反过来,多 goroutine 交叉读写同一批 key 时 misses 频繁触发 dirty 提升(一次 O(n) 复制),反而不如 RWMutex 加普通 map。使用约束:Load/Store 参数是 any,无类型安全(可用泛型自包一层);遍历要拷贝 read,成本高;entry 删除先打标记再惰性清理。工程上除非压测证明瓶颈且访问模式吻合,优先选简单方案。
追问方向:dirty 提升为 read 时旧 read 的修改会丢吗?泛型能否写出类型安全的 sync.Map?(约 581 字)