hhhh,家人们知道为什么我开始学习golang了么?

---

首先注释里面说sync.Map主要适用于两个场景

  • 读多写少的场景
  • 并发读写都很频繁,但是各个goroutine读写操作对象的交集很小

经过阅读标准库源码,得出以下结论

  1. sync.Map结构体有两个map,一个是read只读map指针(用atomic存储),另一个是被mutex保护的dirtymap
  2. 读逻辑:先从read map里面读,如果没有,再去dirty map里面读
  3. 写逻辑:先从read map里拿到entry,如果没有再去dirty map里拿entry,如果再没有就往dirty map里面插入一个
  4. entry是map的kv中的v,是一根原子指针。可以通过atomic并发读写。
  5. 每次read map读写miss都会让miss++,当miss增长到一定大小后,dirty map会被全盘复制到read map。

read map和dirty map的关系:dirty map=read map + some key-value

  1. read map中的kv,如果v是空的,则不会被存入dirty(但会被标记为expunged)。
  2. 如果store的时候,read map中v是expunged,代表该kv在产生dirty map的时候已经存在了,因此需要被同时写入read map和dirty map

---