为什么需要 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. 【ASP.NET Core】标记帮助器——抽象层

    标记帮助器,即 Tag Helpers.这个嘛,就直接翻译了,叫"标记帮助器",虽然不好听,但只能这样了.当然你翻译为"标记增强器"也行. 所谓标记帮助器,就是 ...

  2. Zstack和vmware的初步印象对比

    先不说话,直接上截图吧,vmware的: zstack的: 读者不知道看出什么名堂没有?把浏览器缩放调到50%,vmware的产品线两页截屏还装不下:zstack虽然也要两屏,但都是块块,大致数了数, ...

  3. vue2安装sass 预编译

    步骤一: 安装node-sass.sass-loader.style-loader npm i node-sass sass-loader style-loader --save-dev 步骤二: 打 ...

  4. 搭建Git服务器教程(整理自腾讯云开发者实验室)

    搭建Git服务器教程(整理自腾讯云开发者实验室) 下载安装 Git Git 是一款免费.开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目. 此实验以 CentOS 7.2 x64 的系统 ...

  5. JZOJ 1075. 【GDKOI2006】新红黑树

    \(\text{Problem}\) A君和B君在玩一种叫做新红黑树的游戏,即在一棵由红枝和黑枝构成的树上轮流砍树枝,每次砍一枝,A君每次只能砍红枝,B君每次只能砍黑枝,当其中某人已经没有树枝砍的时候 ...

  6. POJ1737 连通图

    一句话题意:求一个 \(n\) 点带编号的连通图数量. 吐槽一下:好好一道计数 dp 为什么不加取余????逼着选手写高精度的出题人应该拎出去烧--哦楼天城是出题人是吧哦当我没说我什么都没说我现在就把 ...

  7. LeetCode-2 两数相加题解

    题目来源:力扣(LeetCode)链接:https://leetcode-cn.com/problems/add-two-numbers 题目描述 给你两个 非空 的链表,表示两个非负的整数.它们每位 ...

  8. Servlet一笔记

    Servlet一笔记 一.web相关概念 1. 软件架构 目标 理解B/S 和 C/S的优缺点 讲解 C/S架构 C:Client,客户端:S:Server,服务器 比如:QQ,微信,网游 优点: 显 ...

  9. spring boot 跨域

    spring boot提供了两种跨域配置方式 1.全局跨域 2.局部跨域 全局跨域 package com.tons.config; import org.springframework.contex ...

  10. 【C学习笔记】day3-1 将数组A中的内容和数组B中的内容进行交换。(数组一样大)

    #include <stdio.h> int main() { int a[5]; for (int i = 0; i < 5; i++) { scanf_s("%d&qu ...