golang sync.Map分析,设计思想:读多写少

sync.Map

结构体

type Map struct {

  mu Mutex

  read atomic.Value // readOnly

  dirty map[interface{}]*entry

  misses int

}

sync.Map设计思想(读多写少)

sync.Map 采用“空间换时间”的机制,sync.Map结构体冗余了两个数据结构,分别是:readdirty
写值的时候得通过 Store 方法,的时候使用方法 Load 来读取。

与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数组,造成时间消耗的比较多。

posted @ 2022-05-27 17:44  凌易说-lingyisay  阅读(461)  评论(0编辑  收藏  举报