为什么需要 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. Ajax局部修改页面使用html()内置标签

    今天在写javaweb项目时遇到的一个小问题,在Ajax修改页面时,需要修改一串文字同时部分修改样式, 在对比了text()和html()后,在此记录 text:(无法内嵌标签) html:(可以内嵌 ...

  2. P4525 【模板】自适应辛普森法 1

    \(\text{Solution}\) 题目 \(\text{Simpson}\) 公式: \[\int_l^r f(x) {\mathrm d}x = \frac{(r-l)(f(l)+f(r)+4 ...

  3. JZOJ 6801. NOIP2020.9.19模拟patrick

    题目大意 动态维护数列中大于等于某个数的极长连续段的个数. 思路 我们考虑每段的开头,记为 \(i\),高度为 \(a_i\) 那么此时水淹的高度必然满足 \(a_{i-1} < x \leq ...

  4. 代码随想录算法训练营day21 | leetcode ● 530.二叉搜索树的最小绝对差 ● 501.二叉搜索树中的众数 ● ***236. 二叉树的最近公共祖先

    LeetCode 530.二叉搜索树的最小绝对差 分析1.0 二叉搜索树,中序遍历形成一个升序数组,节点差最小值一定在中序遍历两个相邻节点产生 ✡✡✡ 即 双指针思想在树遍历中的应用 class So ...

  5. Windows 注册表是什么

    注册表的概念 历史发展 在 Windows 3.x 操作系统中,注册表是一个极小文件,其文件名为 Reg.dat,里面只存放了某些文件类型的应用程序关联,大部分的设置是被放在 win.ini.syst ...

  6. 基于C++的OpenGL 08 之基础光照

    1. 引言 本文基于C++语言,描述OpenGL的基础光照 前置知识可参考: 基于C++的OpenGL 07 之颜色 - 当时明月在曾照彩云归 - 博客园 (cnblogs.com) 笔者这里不过多描 ...

  7. LeetCode-2055 蜡烛之间的盘子 及库函数 lower_bound 和 upper_bound学习使用

    来源:力扣(LeetCode)链接:https://leetcode-cn.com/problems/plates-between-candles 题目描述 给你一个长桌子,桌子上盘子和蜡烛排成一列. ...

  8. Linux新手渣渣上路史

    Linux新手渣渣上路史 时至2022年,IT行业的迅速发展大家也有目共睹,IT行业在社会的发展中起着举足轻重的作用.其中一角Linux系统,从诞生到开源,再到现在受大众的欢迎,是一个很好的例子.Li ...

  9. Linux操作命令(六)1.wc命令 2.grep命令 3.正则表达式

    1.wc 命令是一个统计的工具,主要用来显示文件所包含的行.字和字节数 参数 描述 -c 统计字节数 -l 统计行数 -m 统计字符数,这个标志不能与 -c 标志一起使用 -w 统计字数,一个字被定义 ...

  10. Supported OPs and DPU Limitations

    Currently Supported Operators source:https://www.xilinx.com/html_docs/xilinx2019_2/vitis_doc/zmw1606 ...