go在并发情况下使用map
两种方式解决并发访问map
- 读写锁实现并发安全Map
- sync.Map
读写锁实现并发安全Map
并发访问map是不安全的。
所以如果希望在多协程中并发访问map,必须提供某种同步机制,一般情况下通过读写锁sync.RWMutex实现对map的并发访问控制,将map和sync.RWMutex封装一下,可以实现对map的安全并发访问。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | package main import ( "fmt" "sync" ) // M type M struct { Map map [ interface {}] interface {} lock *sync.RWMutex } // Set ... func (m *M) Set(key interface {}, value interface {}) { m.lock.RLock() defer m.lock.RUnlock() m.Map[key] = value } // Get ... func (m *M) Get(key interface {}) interface {} { m.lock.Lock() defer m.lock.Unlock() return m.Map[key] } func main() { Map := &M{ make( map [ interface {}] interface {}), new(sync.RWMutex), } Map.Set(2, "2323" ) Map.Set( "hello" ,343) fmt.Println(Map.Get(2)) fmt.Println(Map.Get( "hello" )) } |
sync.Map
go1.9之后加入了支持并发安全的Map sync.Map。
sync.Map 通过一份只使用原子操作的数据和一份冗余了只读数据的加锁数据实现一定程度上的读写分离,使得大多数读操作和更新操作是原子操作,写入新数据才加锁的方式来提升性能。
1、Store 存 key,value
2、LoadOrStore 取&存
3、Load 取key对应的value
4、Range 遍历所有的key,value
5、Delete 删除key,及其value
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | package main import ( "fmt" "sync" ) func main() { var m sync.Map //Store m.Store(1, "a" ) m.Store(2, "b" ) //LoadOrStore //若key不存在,则存入key和value,返回false和输入的value v,ok := m.LoadOrStore( "1" , "aaa" ) fmt.Println(ok,v) //false aaa //若key已存在,则返回true和key对应的value,不会修改原来的value v,ok = m.LoadOrStore(1, "aaa" ) fmt.Println(ok,v) //false aaa //Load v,ok = m.Load(1) if ok{ fmt.Println( "it's an existing key,value is " ,v) } else { fmt.Println( "it's an unknown key" ) } //Range //遍历sync.Map, 要求输入一个func作为参数 f := func (k, v interface {}) bool { //这个函数的入参、出参的类型都已经固定,不能修改 //可以在函数体内编写自己的代码,调用map中的k,v fmt.Println(k,v) return true } m.Range(f) //Delete m.Delete(1) fmt.Println(m.Load(1)) } |
refer:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
2019-02-21 数据库学习之事务
2019-02-21 pymysql的使用
2019-02-21 pymysql:Mysql拒绝从远程访问的解决办法