sync包-Map


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 之间会交替轮换更新.

Go 1.9 sync.Map揭秘

TonyBai-通过实例深入理解sync.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中执行


一口气搞懂 Go sync.map 所有知识点

亲儿子sync.Map,性能为何不如读写锁+Map?

深度解密Go语言之sync.map

看过这篇剖析,你还不懂 Go sync.Map 吗?

@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.

吐槽sync.Map为什么没有len方法的issue

golang 并发安全Map以及分段锁的实现

文章目录