sync.Map源码原理

sync.Map源码原理(简单介绍)

读写简单原理:
写 : 直接写入dirty
读 :read -> dirty
从源码的原理上很清楚的知道是属于于读写分离。

数据结构
type Map struct {
	mu Mutex
	read atomic.Value // readOnly
	dirty map[interface{}]*entry
	misses int
}
简单介绍:
mu锁 会发生并发冲突时需要用到
read 可看作专门用于读取数据的map
dirty 可看作专门存储数据的map
misses 计数,read读取失败+1,当到一定值时,dirty会将值赋给read


read atomic.Value 读map里面的具体结构如下:
type readOnly struct {
    m  map[interface{}]*entry	//map
    amended bool 		//用作比较 Map.dirty的数据和这里的 m 中的数据不一样的时候,为true
}
amended好处在于  如果read和 dirty是一致的 。 就可以通过read 进行无锁读取,这样大大的降低了使用锁的时间.

1.查询:
 1.先查read如果没有 再查dirty
  2.当没查到read 查到dirty里有值,则misses加1
  3.读取dirty 会进行加锁.

2.删除:
   1.首选都会根据read来.
   2.如果read存储则会把read对应value赋值nil(采用标记的方式删除!) 原子性的进行修改
  3.如果read不存在 则会进入dirty进行删除。	加锁解决并发问题

3.新增和修改
优先级进行执行
1.如果read有值 没有被标记删除 则 直接进行修改 原子性修改
2.否则加锁执行下面操作
3.read有值 被标记删除 。 则恢复成expunged 在修改值 原子性修改
4.dirty有值 则进行修改 原子性修改
5.read 和 dirty都没有 
将read中未删除的数据加入到dirty中
amended标记为read与dirty不相同,因为后面即将加入新数据



使用场景 : 读多写少,如果经常写,就需要一直在dirty进行读取,还会有dirty和read的一个过程.这样就得不偿失了.
如果写多读多,可以考虑自己实现个类似于 mysql主键行锁那样
map嵌套一个小map
某些一部分的key value在小map
另外一部分 又在 另一个 小map
使用hash等一些办法 。 通过key找到对应的小map即可
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值