03.sync_map ✅
# 01.sync.Map介绍
# 1、sync.Map介绍
sync.Map是 Go 语言在sync包中提供的一个并发安全的 map 实现- 旨在解决高并发环境下使用普通 map 时需要手动加锁带来的性能瓶颈问题
sync.Map通过精心设计的读写机制,保证了在多线程环境下对 map 进行高效的读写操作
# 2、sync.Map特点
read结构是无锁的,因此读取性能非常高
dirty操作涉及加锁,但加锁操作被限制在写入和未命中的情况下,避免了频繁的锁争用
read:
- 一个不变的只读数据结构,它存储了最近的键值对,并且支持并发安全的无锁读操作
sync.Map尽可能地从read中读取数据,因为read是无锁的,因此读操作非常高效
dirty:
- 一个允许修改的 map,用来存储更新后的数据
- 只有当某个键不存在于
read中时,才会从dirty中查询数据 - 读写
dirty是需要加锁的 - 当
dirty和read之间不一致时,数据将首先写入dirty,随后会尝试将部分数据推广到read中
misses:
- 一个计数器,用来统计从
read中未命中(即read中没有找到键值对)且从dirty中成功读取的次数 - 当
misses达到一定数量时,会将dirty中的数据复制到read,以提升读取命中率并减少锁争用
- 一个计数器,用来统计从
// Map结构体
type Map struct {
mu Mutex // 当涉及到脏数据(dirty)操作时候,需要使用这个锁
read atomic.Value // 不变的只读数据结构
dirty map[interface{}]*entry // 主要用来写,部分时候也承担读的能力
misses int // 记录自从上次更新了read之后,从read读取key失败的次数
}
// readOnly结构体
type readOnly struct {
// m包含所有只读数据,不会进行任何的数据增加和删除操作
// 但是可以修改entry的指针因为这个不会导致map的元素移动
m map[interface{}]*entry
amended bool // 标志位,如果为true则表明当前read只读map的数据不完整
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 3、 dirty 同步 read情况
1)
misses达到阈值时
- 当读取操作在
read中未找到指定的键(未命中),并且从dirty中成功读取时,sync.Map会增加misses计数
2)写入新
key-value时
- 当要往
sync.Map中写入一个新的key-value对时,系统会检查read和dirty之间的差异 - 如果
read中的数据较旧,且dirty已经有更新,系统会先将dirty中的数据同步到read - 目的:通过在写入之前同步
read和dirty,系统确保read尽量保持最新数据,从而减少未来读操作对dirty的访问
3)
dirty为nil时
- 如果
dirty为nil,意味着此时所有的数据都在read中,且没有写入过任何更新 - 目的:确保写操作发生在
dirty中,同时保持read不变以供无锁读取
# 02.sync.Map操作

# 1、 写入操作
1、
key原先就存在于read中,获取key所对应内存地址,原子性修改2、
key原先就存在于read中,但是key所对应的值被标记为删除状态- 解除标记,并更新dirty中的key,将
dirty中的数据批量同步到read,然后修改key对应的值
- 解除标记,并更新dirty中的key,将
3、
read中没有key,但是dirty中存在这个key,直接修改dirty中key的值4、
read和dirty中都没有值,先同步read和dirty的值,然后添加新的key value到dirty上面
# 2、删除数据
- 1、read中没有,且Map存在修改,则尝试删除dirty中的map中的key
- 2、read中没有,且Map不存在修改,那就是没有这个key,无需操作
- 3、read中有,尝试将key对应的值设置为nil,后面读取的时候就知道被删了,
因为dirty中map的值跟read的map中的值指向的都是同一个地址空间,所以,修改了read也就是修改了dirty
# 3、读取
如果在
read中找到了键值对,则直接返回结果,整个过程是无锁的如果未命中,则尝试从
dirty中读取,此时需要加锁为了优化性能,在dirty中找到了数据后,会增加misses计数如果
misses达到阈值,则会将dirty中的内容同步到read中
上次更新: 2025/4/29 17:38:19