golang中的sync.Map
Go 语言中的 map 在并发情况下,只读是线程安全的,同时读写线程不安全。
下面来看下并发情况下读写 map 时会出现的问题,代码如下:
package mainfunc main() {//创建一个int到int映射m := make(map[int]int)//开启一段并发代码go func() {//不停对map进行写入for {m[1] = 1}}()//开启一段并发代码go func() {//不停对map进行读取for {_ = m[1]}}()for {;}
}
运行代码会报错,输出如下:
fatal error: concurrent map read and map write
运行时输出提示:并发的 map 读写。也就是说使用了两个并发函数不断地对 map 进行读和写而发生了竞态问题。map 内部会对这种并发操作进行检查并提前发现。
需要并发读写时,一般的做法是加锁,但这样性能并不高。Go 语言在 1.9 版本中提供了一种效率较高的并发安全的 sync.Map。sync.Map 和 map 不同,不是以语言原生形态提供,而是在 sync 包下的特殊结构。
sync.Map有以下特性:
- 无须初始化,直接声明即可。
- sync.Map 不能使用 map 的方式进行取值和设置等操作,而是使用 sync.Map 的方法进行调用。Store 表示存储,Load 表示获取,Delete 表示删除。
- 使用 Range 配合一个回调函数进行遍历操作,通过回调函数返回内部遍历出来的值。Range 参数中的回调函数的返回值功能是:需要继续迭代遍历时,返回 true;终止迭代遍历时,返回 false。
package mainimport ("fmt""sync"
)func main() {var scene sync.Map// 将键值对保存到sync.Mapscene.Store("greece", 97)scene.Store("london", 100)scene.Store("egypt", 200)// 从sync.Map中根据键取值fmt.Println(scene.Load("london"))// 根据键删除对应的键值对scene.Delete("london")// 遍历所有sync.Map中的键值对scene.Range(func(k, v interface{}) bool {fmt.Println("iterate:", k, v)return true})}
代码输出如下:
100 true
iterate: egypt 200
iterate: greece 97
代码说明如下:
- 第 10 行,声明 scene,类型为 sync.Map。注意,sync.Map 不能使用 make 创建。
- 第 13~15 行,将一系列键值对保存到 sync.Map 中,sync.Map 将键和值以 interface{} 类型进行保存。
- 第 18 行,提供一个 sync.Map 的键给 scene.Load() 方法后将查询到键对应的值返回。
- 第 21 行,sync.Map 的 Delete 可以使用指定的键将对应的键值对删除。
- 第 24 行,Range() 方法可以遍历 sync.Map,遍历需要提供一个匿名函数,参数为 k、v,类型为
interface{}
,每次 Range() 在遍历一个元素时,都会调用这个匿名函数把结果返回。
sync.Map 没有提供获取 map 数量的方法,替代方法是获取时遍历自行计算数量。sync.Map 为了保证并发安全有一些性能损失,因此在非并发情况下,使用 map 相比使用 sync.Map 会有更好的性能。
golang中的sync.Map相关推荐
- golang中并发sync和channel
golang中并发sync和channel chenbaoke · 2014-12-08 13:00:01 · 19151 次点击 · 预计阅读时间 5 分钟 · 不到1分钟之前 开始浏览 这是一个创 ...
- golang中的sync.WaitGroup
golang中的sync.WaitGroup Posted on 2015/04/09刚才看golang的sync的包,看见一个很有用的功能.就是WaitGroup. 先说说WaitGroup的用途: ...
- golang中的sync.once
sync.Once.Do(f func())是一个挺有趣的东西,能保证once只执行一次,无论你是否更换once.Do(xx)这里的方法,这个sync.Once块只会执行一次 与sync.WaitGr ...
- Golang sync.Map 原理(两个map实现 读写分离、适用读多写少场景)
参考: 由浅入深聊聊Golang的sync.Map 通过对源码的逐行分析,清晰易懂 Golang sync.Map原理 通过向 sync.Map 中增删改查来介绍sync.Map的底层原理 Golan ...
- golang 中 map 转 struct
golang 中 map 转 struct package mainimport ("fmt""github.com/goinggo/mapstructure" ...
- golang sync.Map 使用
自1.9版本以后提供了sync.Map,支持多线程并发读写,比之前的加锁map性能要好一点. 提供一下几个方法: type Map//删除指定keyfunc (m *Map) Delete(key i ...
- c语言map函数k v都是int,Go语言sync.Map(在并发环境中使用的map)
Go语言中的 map 在并发情况下,只读是线程安全的,同时读写是线程不安全的. 下面来看下并发情况下读写 map 时会出现的问题,代码如下: // 创建一个int到int的映射 m := make(m ...
- golang中的atomic,以及CAS操作
CAS无锁算法 要实现无锁(lock-free)的非阻塞算法有多种实现方法,其中CAS(比较与交换,Compare and swap)是一种有名的无锁算法.CAS是CPU指令,在大多数处理器架构,包括 ...
- 记一次golang中sync.Map并发创建、读取的问题
记一次golang中sync.Map并发创建.读取的问题 cunfate https://www.jianshu.com/p/f472e79909bc 背景: 我们有一个用go做的项目,其中用到了z ...
最新文章
- 趣图:老手调试多线程,666
- JavaSE基础知识(5)—面向对象(5.2类的成员)
- 因式分解,算术基本定理,积性函数(POJ 1452 Happy2004)
- 「Algospot」津巴布韦ZIMBABWE
- java keygenerator_Java密码学KeyGenerator类
- 图片抓取_小小爬虫批量抓取微信推文里的图片
- 软考信息系统项目管理师_管理科学(运筹学)2---软考高级之信息系统项目管理师034
- java map size 不准确_java1.7以前ConcurrentHashMap的size方法
- 商业数据库之死:Oracle 的困境
- mysql打开数据库命令_MySQL操作数据库指令
- 大数据学习相关内容总结
- java 查看类_JAVA基础知识之JVM-——通过反射查看类信息
- Xilinx 7系列FPGA收发器架构之硬件设计指导(一)
- [RK3588-Android12] Uboot-Logo引起的 HDMI第一次开机无声音问题
- 云计算大数据学习中心作业2
- 利用 Global mapper制作地图瓦片
- java电子邮件收发系统,基于Java_Mail的电子邮件收发系统毕业设计
- 【数据结构与算法基础】AOE网络与关键路径
- Cookie-网站登录-下次自动登录
- 输出自己的姓名python_【Python编程:显示自己的的姓名和学号,并将学号各位数字相加求和,并显示.】...
热门文章
- 【Netty】Netty 核心组件 ( Pipeline | ChannelPipeline )
- 【Android 系统开发】 Android 系统启动流程简介
- 提升vector性能的几个技巧
- 【刷题记录】杂题记录
- 全国计算机技术与软件专业技术资格(水平)考试【软件评测师】-考试内容总结(四)中间件基础知识...
- PYTHON调用JENKINS的API来进行CI
- moveit!功能包安装问题
- PostgreSQL 当有多个索引可选时,优化器如何选择
- Vue.js 插件开发详解
- 5 个关于 API 中日期和时间设计规则