sync.Map源码阅读笔记

/ 0评 / 1

写在前面的碎碎念

Go的原生map不是并发安全的,多个协程并发读写map被竞态检测到时会直接panic掉整个进程,recover都不能cover住...因此在写代码时,只要关于并发读写map都要谨记并发安全,印象中之前组里有出过这样的bug,凌晨左右发现服务莫名其妙挂掉。
关于map的最简单并发安全处理就是暴力加锁了,互斥锁,读写锁都可以,当然能用,但是锁粒度在某些性能要求较高的场景下显然的问题。
Go官方不愿意把原生的map做复杂这点,个人认为是对的,因为map这种离散存储数据的结构,要做成并发安全会过于复杂(关于这点看看map源码可以知道,Go的map中间操作非常多),很多时候我们也不需要一个并发安全的map,同时,原生库若是发布后出问题了大家也会很尴尬。
于是Go官方基于读写分离设计并实现了一个并发安全的sync.Map,其主要对满足以下任一条件的场景进行优化(相比起简单加锁):

这两个场景之外的任何情况,sync.Map的性能都未必比暴力加锁要好,不要滥用sync.Map。

实现原理

sync.Map的实现原理有很多优秀文章了,以下是我自己仔细看过的两篇,都讲的非常清楚,附上链接以供阅读:
由浅入深聊聊Golang的sync.Map
golang-sync.Map实现原理
有一点是这些文章都没讲到的,且非常容易让人不理解sync.Map的readOnly为何不用加锁。因此特别指明一下:map并发读写不安全,但是纯并发读是安全的。

发表评论

电子邮件地址不会被公开。 必填项已用*标注