前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Go语言sync.Map

Go语言sync.Map

作者头像
孤烟
发布2022-11-07 15:00:13
4950
发布2022-11-07 15:00:13
举报
文章被收录于专栏:golang开发笔记

Go语言中的 map 在并发情况下,只读是线程安全的,同时读写是线程不安全的。 如果想实现并发线程安全有两种方法:

  • map加互斥锁或读写锁
  • 标准库sync.map(Go1.19+新特性)

sync.map源码

https://github.com/golang/go/...

sync.map 实现原理及优化

  • 利用map只读不用锁,通过冗余 read 和 dirty 两个字段将读写分离,读的数据存在只读字段 read 上,将最新写入的数据则存在 dirty 字段上,只在dirty读写上加锁,提高程序只读效率。
  • 读取时会先查询 read,不存在再查询 dirty,写入时则只写入 dirty
  • 读取 read 并不需要加锁,而读或写 dirty 都需要加锁
  • 另外有 misses 字段来统计 read 被穿透的次数(被穿透指需要读 dirty 的情况),超过一定次数则将 dirty 数据同步到 read 上
  • 对于删除数据则直接通过标记来延迟删除

具体数据结构可参考: https://blog.csdn.net/u010853... https://www.haohongfan.com/do...

sync.map 使用场景

map+Mutex: 通过Mutex互斥锁来实现多个goroutine对map的串行化访问,读写都需要通过Mutex加锁和释放锁,适用于读写比接近的场景 map+RWMutex:通过RWMutex来实现对map的读写进行读写锁分离加锁,从而实现读的并发性能提高,同Mutex相比适用于读多写少的场景 sync.Map:底层通分离读写map和原子指令来实现读的近似无锁,并通过延迟更新的方式来保证读的无锁化。读多修改少,元素增加删除频率不高的情况,在大多数情况下替代上述两种实现

sync.map 使用方法如下

代码语言:javascript
复制
package main

import (
    "fmt"
    "sync"
)

func main() {
    var m sync.Map
    //添加一个元素
    m.Store(1, "a")
    m.Store("a", 2)

    //读取一个元素
    fmt.Println(m.Load(1))   //a true
    fmt.Println(m.Load("a")) //2 true

    //读取不存在的元素
    fmt.Println(m.Load(2)) //<nil> false

    //存在就返回,不存在就插入
    fmt.Println(m.LoadOrStore("3", 33)) //33 false
    fmt.Println(m.Load("3"))            //33 true

    //如果存在的话,同时删除这个 key
    fmt.Println(m.LoadAndDelete("3")) // 33 true

    //删除某个元素
    m.Delete("3")
    // 遍历所有sync.Map中的键值对
    m.Range(func(k, v interface{}) bool {
        fmt.Println("iterate:", k, v)
        return true
    })
}

通过以上示例可以看到sync.map具有以下特性:

  • 可以存储不同的数据类型在一起,这有别于map只能存储声明好的数据类型,且相同的。
  • 无须初始化,直接声明即可。
  • sync.Map 不能使用map的方式进行取值和设置等操作,而是使用 sync.Map 的方法进行调用,Store 表示存储,Load 表示获取,Delete 表示删除
  • 增加了两个特殊方法LoadOrStore 存在就返回,不存在就插入,LoadAndDelete 如果存在的话,同时删除这个 key
  • 使用 Range 配合一个回调函数进行遍历操作,通过回调函数返回内部遍历出来的值,Range 参数中回调函数的返回值在需要继续迭代遍历时,返回 true,终止迭代遍历时,返回 false。

参考资料

https://juejin.cn/post/684490... https://pkg.go.dev/sync#Map https://blog.csdn.net/u010853... https://medium.com/@deckarep/... https://www.haohongfan.com/do...

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-10-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • sync.map源码
  • sync.map 实现原理及优化
  • sync.map 使用场景
  • sync.map 使用方法如下
  • 参考资料
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档