一、sync.Map的使用
1.Map的增加、删除、获取、遍历
package main
import (
"fmt"
"sync"
)
type Person struct {
name string
age int32
}
var personList sync.Map
func main () {
personList.Store(11111, &Person{"Sam", 21})
personList.Store(11112, &Person{"Sam1", 22})
personList.Store(11113, &Person{"Sam2", 23})
personList.Store(11114, &Person{"Sam3", 24})
personList.Range(func(key, value interface{}) bool {
node := value.(*Person)
fmt.Println(key, node.name, node.age)
return true
})
personList.Delete(11111)
personList.Delete(11112)
if value, ok := personList.Load(11111); ok {
fmt.Println(value)
} else {
fmt.Println("Sam has been deleted")
}
if value, ok := personList.Load(11113); ok {
fmt.Println(value)
} else {
fmt.Println("Sam3 has been deleted")
}
}

二、sync.Map的原理
- 通过 read 和 dirty 两个字段将读写分离
- 读的数据存在只读字段 read 上,将最新写入的数据则存在 dirty 字段上
- 读取时会先查询 read,不存在再查询 dirty,写入时则只写入 dirty
- 读取 read 并不需要加锁,而读或写 dirty 都需要加锁
- 另外有 misses 字段来统计 read 被穿透的次数(被穿透指需要读 dirty 的情况),超过一定次数则将 dirty 数据同步到 read 上
- 对于删除数据则直接通过标记来延迟删除
三、参考资料
juejin.cn/post/684490…