为什么需要 sync map

go 语言之所以引入 sync.Map主要是因为GO 语言自带的 map 是线程不安全的。只能保证并发的读,但是不能保证并发的写。

看下面的例子:

func main() {
m := make(map[int]int)
go func() {
for {
m[1] = 1 // 并发的写
}
}()
go func() {
for {
_ = m[1] //并发的读
}
}()
time.Sleep(time.Hour)
}

运行结果如下

注意:

  1. 出现这种现象的原因,主要是因为:错误信息显示,并发的 map 读和 map 写,也就是说使用了两个并发函数不断地对 map 进行读和写而发生了竞态问题,map 内部会对这种并发操作进行检查并提前发现。

  2. 其实,就算你在 第一个协程和第二个协程中间,加上 time.Sleep(time.Second) ,依然也会报 panic

使用 sync.map

代码如下,再并发的读写,就不会报错了。

func main() {
var m sync.Map
go func() {
m.Store(1, "小张")
}()
time.Sleep(time.Second)
go func() {
v, ok := m.Load(1)
if ok {
fmt.Println(v.(string))
}
}()
time.Sleep(time.Second)
}

如果想把 sync.map 中的 key 和 value 遍历出来,需要用 sync.map 自带的特殊方法

func main() {
var m sync.Map
go func() {
m.Store(1, "小张")
}()
time.Sleep(time.Second)
go func() {
v, ok := m.Load(1)
if ok {
fmt.Println(v.(string))
}
}()
time.Sleep(time.Second) // 遍历 sync.map 中的 key,val
m.Range(func(key, value interface{}) bool {
fmt.Println("key:", key.(int), "value", value.(string))
if key.(int) == 2 {
return false
}
return true
})
} // 输出结果如下
小张
key: 1 value 小张
key: 2 value 小王

注意:

  1. sync.map 无须初始化,直接声明即可。

  2. sync.Map 不能使用 map 的方式进行取值和设置等操作,而是使用 sync.Map 的方法进行调用,Store 表示存储,Load 表示获取,Delete 表示删除。

  3. 使用 Range 配合一个回调函数进行遍历操作,通过回调函数返回内部遍历出来的值,Range 参数中回调函数的返回值在需要继续迭代遍历时,返回 true,终止迭代遍历时,返回 false。

  4. sync.Map 为了保证并发安全有一些性能损失,因此在非并发情况下,使用 map 相比使用 sync.Map 会有更好的性能。

GO 语言中的 sync Map的更多相关文章

  1. Go语言中映射表map的使用

    1 概述 Go语言中的键值对(key->value)集合,称之为映射map.映射map是变长类型,定义时不需要指定长度.映射map是无序的,遍历是的顺序不可期,原因是底层由hash表实现.逻辑结 ...

  2. sync.Map(在并发环境中使用的map)

    sync.Map 有以下特性: 需要并发读写时,一般的做法是加锁,但这样性能并不高,Go语言在 1.9 版本中提供了一种效率较高的并发安全的 sync.Map,sync.Map 和 map 不同,不是 ...

  3. 深入理解golang:sync.map

    疑惑开篇 有了map为什么还要搞个sync.map 呢?它们之间有什么区别? 答:重要的一点是,map并发不是安全的. 在Go 1.6之前, 内置的map类型是部分goroutine安全的,并发的读没 ...

  4. Go语言中的并发编程

    并发是编程里面一个非常重要的概念,Go语言在语言层面天生支持并发,这也是Go语言流行的一个很重要的原因. Go语言中的并发编程 并发与并行 并发:同一时间段内执行多个任务(你在用微信和两个女朋友聊天) ...

  5. golang中的sync

    1. Go语言中可以使用sync.WaitGroup来实现并发任务的同步 package main import ( "fmt" "sync" ) func h ...

  6. 深度解密 Go 语言之 sync.map

    工作中,经常会碰到并发读写 map 而造成 panic 的情况,为什么在并发读写的时候,会 panic 呢?因为在并发读写的情况下,map 里的数据会被写乱,之后就是 Garbage in, garb ...

  7. golang 标准库 sync.Map 中 nil 和 expunge 区别

    本文不是 sync.Map 源码详细解读,而是聚焦 entry 的不同状态,特别是 nil 状态和 expunge 状态的区分. entry 是 sync.Map 存放值的结构体,其值有三种,分别为 ...

  8. go 语言中常用的包

    来自学习go语言.pdf 译者刑星 ==== fmt 包fmt实现了格式化IO函数,这与c的printf和scanf类似,格式化短语派生于c %v 默认格式的值.当打印结构时,加号(%+v)会增加字段 ...

  9. Go 1.9 sync.Map揭秘

    Go 1.9 sync.Map揭秘 目录 [−] 有并发问题的map Go 1.9之前的解决方案 sync.Map Load Store Delete Range sync.Map的性能 其它 在Go ...

  10. 图解Go里面的sync.Map了解编程语言核心实现源码

    基础筑基 在大多数语言中原始map都不是一个线程安全的数据结构,那如果要在多个线程或者goroutine中对线程进行更改就需要加锁,除了加1个大锁,不同的语言还有不同的优化方式, 像在java和go这 ...

随机推荐

  1. 栈——stack的用法

    介绍 栈(stack)又名堆栈,它是一种运算受限的线性表.限定仅在表尾进行插入和删除操作的线性表.这一端被称为栈顶,相对地,把另一端称为栈底.向一个栈插入新元素又称作进栈.入栈或压栈,它是把新元素放到 ...

  2. centos7.6安装teamviewer-原来还可以用yum 安装rpm包,自动解决依赖,太爽了

    1.在官网下载teamviewer安装包 2.安装.一直用rpm -ivh 的方式安装rpm包,但是不会自动解决依赖,今天才知道,原来还可以用yum -y install rpm包,自动解决依赖. [ ...

  3. Cesium计算多边形面积(十一)

    //计算三角形面积 function triangleArea(p0, p1, p2) { let v0 = Cesium.Cartesian3.subtract(p0, p1, new Cesium ...

  4. 如何基于IM即时通讯SDK从零开发仿微信聊天交友功能

    IM即时通讯技术的发展 IM即时通讯(Instant Messaging)是一种基于互联网的即时交流消息的业务. 实时聊天交互功能是市面上主流APP的重要功能之一,人们所熟悉的就是微信,QQ的聊天消息 ...

  5. NodeJs设置全局缓存路径 和 安装CNPM

    设置全局路径 下建立2个文件夹 如"node_global"及"node_cache" , npm config set prefix "D:\Pro ...

  6. C#判断useragent是pc还是手机端

    public static bool CheckAgent(string userAgent) { bool flag = false; string[] keywords = { "And ...

  7. Hadoop YARN与MapReduce

    YARN架构 ResourceManager      负责整体资源的管理 (Scheduler and ApplicationsManager)NodeManager     向ResourceMa ...

  8. Truenas core 13连接LDAP,获取AD域用户及自动分配权限---chatGPT回复,未做证实

    要在TrueNAS Core 13上连接LDAP并从AD域中获取用户,请按照以下步骤操作: 在TrueNAS Core 13上登录到WebUI. 转到"网络"菜单并选择" ...

  9. 银河麒麟V10安装MySQL5.7

      环境: Kylin-Server-10-SP2-Release-Build09-20210524-x86_64.isomysql-5.7.28-linux-glibc2.12-x86_64.tar ...

  10. Vulnhub:katana靶机

    kali:192.168.111.111 靶机:192.168.111.194 信息收集 端口扫描 目录爆破发现80端口/ebook/database目录下的readme.txt.txt文件提示用户密 ...