赞
踩
通过以上几个方面,我们了解了map底层实现,并且知道map不是并发安全的,那么golang有没有提供并发安全的map呢?答案是yes,那就是sync.map。Go官方在2017年发布的Go1.9中,正式加入了并发安全的字典类型sync.map,该map有以下几个特点:
下面我们通过分析sync.map中的源码,来看上面第1点和第2点是如何做到的
结构体包含Map、readOnly、entry。
其中Map中包含了两个map:
(1)一个优先读map:read,read不是只允许只读,它是可以有写操作的,但是只允许对已存在的值进行写操作,不允许增加新元素,删除也只是做标记,并不是真正的删除。即键的集合不能被改变,所以键值是不全的
(2)一个需要加锁进行操作的读写map:dirty,其中的键值对集合总是完全的,而且不包含已被逻辑删除的键值对
这两个map是实现并发安全的关键所在
type Map struct{
m Mutex //互斥锁,用于对dirty进行加锁
read atomic.Value //优先读map,支持原子操作,并不是只读map,可以有写操作
dirty map[interface{}]*entry //当前最新map,需要加锁操作,允许读写,
misses int //记录read读取不到数据,需要加锁读取的次数,当misses等于dirty的长度时,会将dirty复制到read
}
readOnly是存储在read中的元素
type readOnly struct{
m map[interface{}]*entry// 该map中存储的entry指针,与dirty中存储的entry指针一样,因此虽然引入的两个map,但是底层存的是指针
amended bool //amended为false时,代表dirty中还没有数据,如果dirty中存在一些在read中没有的数据,则该值为true,可以看作修改的标记
}
entry存放着真正的实体数据
type entry struct{
p unsafe.Pointer
//其中p有如下Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。