Golang - map并发不安全及解决方法
相关面试题
- map的底层实现原理
- 为什么遍历map是无序的?
- 如何实现有序遍历map?
- 为什么Go map是非线程安全的?
- 线程安全的map如何实现?
- Go sync.map 和原生 map 谁的性能好,为什么?
- 为什么 Go map 的负载因子是 6.5?
- map扩容策略是什么?
1、map默认是并发不安全的,原因如下:
1)、 典型使用场景:map 的典型使用场景是不须要从多个 goroutine 中进行安全访问;
2)、非典型场景(须要原子操做):map 多是一些更大的数据结构或已经同步的计算的一部分;
3)、性能场景考虑:如果只是为少数程序增长安全性,致使 map 全部的操做都要处理 mutex,将会下降大多数程序的性能。
Go 官方团队在经过了长时间的讨论后,认为 Go map 更应适配典型使用场景(不需要从多个 goroutine 中进行安全访问),而不是为了小部分情况(并发访问),导致大部分程序付出加锁代价(性能),所以决定了不支持并发安全。
2、如果想实现map线程安全,有两种方式:
方式一:使用读写锁 map
+ sync.RWMutex
方式二:使用golang提供的 sync.Map
sync.Map是用读写分离实现的,其思想是空间换时间。和map+RWLock的实现方式相比,它做了一些优化:可以无锁访问read map,而且会优先操作read map,倘若只操作read map就可以满足要求(增删改查遍历),那就不用去操作write map(它的读写都要加锁),所以在某些特定场景中它发生锁竞争的频率会远远小于map+RWLock的实现方式。
总结
- map是引用类型
- map遍历是无序的
- map是非线程安全的
- map的哈希冲突解决方式是链表法
- map的扩容不一定会新增空间,也有可能是只是做了内存整理
- map的迁移是逐步进行的,在每次赋值时,会做至少一次迁移工作
- map中删除key,有可能导致出现很多空的kv,这会导致迁移操作,如果可以避免,尽量避免
分类:
Golang
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」