hhhh,家人们知道为什么我开始学习golang了么?
---
首先注释里面说sync.Map主要适用于两个场景
- 读多写少的场景
- 并发读写都很频繁,但是各个goroutine读写操作对象的交集很小
经过阅读标准库源码,得出以下结论
- sync.Map结构体有两个map,一个是read只读map指针(用atomic存储),另一个是被mutex保护的dirtymap
- 读逻辑:先从read map里面读,如果没有,再去dirty map里面读
- 写逻辑:先从read map里拿到entry,如果没有再去dirty map里拿entry,如果再没有就往dirty map里面插入一个
- entry是map的kv中的v,是一根原子指针。可以通过atomic并发读写。
- 每次read map读写miss都会让miss++,当miss增长到一定大小后,dirty map会被全盘复制到read map。
read map和dirty map的关系:dirty map=read map + some key-value
- read map中的kv,如果v是空的,则不会被存入dirty(但会被标记为expunged)。
- 如果store的时候,read map中v是expunged,代表该kv在产生dirty map的时候已经存在了,因此需要被同时写入read map和dirty map
---