sync.map 则是一种并发安全的 map,在 Go 1.9 引入
本文是对 Golang sync.Map 实现原理的学习与记录
sync.Map 的特点是冗余了两份 map:read map 和 dirty map,
主线一:首先基于无锁操作访问 read map;倘若 read map 不存在该 key,则加锁并使用 dirty map 兜底;
主线二:read map 和 dirty map 之间会交替轮换更新.
sync.Map 支持并发读写 map,但写入性能较差,更适用于读多写少的场景
sync.Map内部使用读写分离机制,即耗时较长的写操作与耗时较短的读操作分离,放在两个容器中进行(有read和dirty两个容器,其中写操作优先放在dirty中进行,读操作优先放在read中进行),极大提高了map的并发性能,且不用管理锁机制,使用起来更加便捷。(空间换时间,使用 read 和 dirty 两个 map 来进行读写分离,降低锁时间来提高效率)
读写分离的优点在于:
- 执行读操作时不用加锁,仅写操作需要加锁
- 在dirty存在时,写操作都放在dirty中执行,不影响read中的读操作,因此当读的元素在read中时,是可以并发读写的
在对sync.Map的增、删、改、查操作时,都是先对read做操作,再对dirty操作。因此read中做标记可以有效减少对dirty的无效操作,nil表示dirty未创建,无需对dirty操作,expunged表示dirty创建成功,写操作可以放入dirty中执行
@bcmills Do not you think it’s very ridiculous that Go has a built in func len for map while sync.Map does not have a corresponding function func (Map)Len() int to get its size?
No, I don’t think it’s “very [ridiculous]”. Concurrent data structures are not the same as unsynchronized data structures. The built-in map type doesn’t have (and doesn’t need) a LoadOrStore, for example.
We should decide the API of each type based on its own tradeoffs. Consistency is a benefit, but there are costs to weigh it against.
原文链接: https://dashen.tech/2020/03/02/sync包-Map/
版权声明: 转载请注明出处.