sync.Map
结构体
type Map struct {
mu Mutex
read atomic.Value // readOnly
dirty map[interface{}]*entry
misses int
}
sync.Map设计思想(读多写少)
readdirty
与map+RWMutex的实现并发的方式相比,减少了加锁对性能的影响。
它做了一些优化:可以无锁访问read map,而且会优先操作read map,倘若只操作rede map就可以满足要求,那就不用去操作write map(dirty)。
所以在某些特定场景中它发生锁竞争的频率会远远小于map + RWMutex的实现方式。
优点:适合读多写少的场景;
缺点:如果是写多的场景,会导致read map缓存失效,需要加锁,冲突突变,性能急剧下降。
map并发写就用map+sync.Mutex效率更高,sync.Map性能比较低1580ns/op
珂哥讲技术:
sync.Map有两个数组,read数组和dirty数组(脏数组),写入map他会发现,read里面没有就写到dirty数组里面1:1,2:2 ,想读key=1的值发现read数组里面没有,加锁从dirty数组里面找,找到不到命中计数器++(miss计数器),当miss++>len(dirty),它就会把dirty里面的数据拷贝到read数组里面,然后把dirty里面的数据清理掉,读是不加锁特别快,
改写1:11,首先在read数组把11进行原子操作,数据交换,同时会在dirty数组里面写进去;写一个新的数据3会写到dirty数组里面,同样原理read的时候没有命中就去dirty数组里面数据拷贝到read数组里面,清理到dirty数组的全部数据 。所以为什么sync.Map读快是因为不加锁,写慢是因为加锁,同时在写的时候还会再去读一次read数组,造成时间消耗的比较多。