Go使用sync.Map来解决map的并发操作问题

目录
  • 前言
  • map 并发操作出现问题
  • sync.Map 解决并发操作问题
  • 计算 map 长度
  • 计算 sync.Map 长度

前言

在 Golang 中 map 不是并发安全的,自 1.9 才引入了 sync.Map ,sync.Map 的引入确实解决了 map 的并发安全问题,不过 sync.Map 却没有实现 len() 函数,如果想要计算 sync.Map 的长度,稍微有点麻烦,需要使用 Range 函数。

map 并发操作出现问题

func main() {
 demo := make(map[int]int)

 go func() {
  for j := 0; j < 1000; j++ {
   demo[j] = j
  }
 }()

 go func() {
  for j := 0; j < 1000; j++ {
   fmt.Println(demo[j])
  }
 }()

 time.Sleep(time.Second * 1)
}

执行输出:

fatal error: concurrent map read and map write

sync.Map 解决并发操作问题

func main() {
 demo := sync.Map{}

 go func() {
  for j := 0; j < 1000; j++ {
   demo.Store(j, j)
  }
 }()

 go func() {
  for j := 0; j < 1000; j++ {
   fmt.Println(demo.Load(j))
  }
 }()

 time.Sleep(time.Second * 1)
}

执行输出:
<nil> false
1 true

...

999 true

计算 map 长度

func main() {
 demo := make(map[int]int)

 for j := 0; j < 1000; j++ {
  demo[j] = j
 }

 fmt.Println("len of demo:", len(demo))
}

执行输出:
len of demo: 1000

计算 sync.Map 长度

func main() {
 demo := sync.Map{}

 for j := 0; j < 1000; j++ {
  demo.Store(j, j)
 }

 lens := 0
 demo.Range(func(key, value interface{}) bool {
  lens++
  return true
 })

 fmt.Println("len of demo:", lens)
}

执行输出:
len of demo: 1000

小结

  • Load 加载 key 数据
  • Store 更新或新增 key 数据
  • Delete 删除 key 数据
  • Range 遍历数据
  • LoadOrStore 如果存在 key 数据则返回,反之则设置
  • LoadAndDelete 如果存在 key 数据则删除

到此这篇关于Go使用sync.Map来解决map的并发操作问题的文章就介绍到这了,更多相关Go sync.Map解决map并发操作内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • golang 并发安全Map以及分段锁的实现方法

    涉及概念 并发安全Map 分段锁 sync.Map CAS ( Compare And Swap ) 双检查 分断锁 type SimpleCache struct { mu sync.RWMutex items map[interface{}]*simpleItem } 在日常开发中, 上述这种数据结构肯定不少见,因为golang的原生map是非并发安全的,所以为了保证map的并发安全,最简单的方式就是给map加锁. 之前使用过两个本地内存缓存的开源库, gcache, cache2go,其中

  • 快速解决Golang Map 并发读写安全的问题

    一.错误案例 package main import ( "fmt" "time" ) var TestMap map[string]string func init() { TestMap = make(map[string]string, 1) } func main() { for i := 0; i < 1000; i++ { go Write("aaa") go Read("aaa") go Write(&qu

  • Go 并发读写 sync.map 详细

    目录 1.sync.Map 优势 2.性能测试 2.1 压测结果 1)写入 2)查找 3)删除 2.3 场景分析 3.sync.Map 剖析 3.1 数据结构 3.2 查找过程 3.3 写入过程 3.4 删除过程 map 的两种目前在业界使用的最多的并发支持的模式分别是: 原生 map + 互斥锁或读写锁 mutex. 标准库 sync.Map(Go1.9及以后). 有了选择,总是有选择困难症的,这两种到底怎么选,谁的性能更加的好?我有一个朋友说 标准库 sync.Map 性能菜的很,不要用.我

  • Golang实现对map的并发读写的方法示例

    在Golang多协程的情况下使用全局map时,如果不做线程同步,会出现panic的情况. 为了解决这个问题,通常有两种方式: 第一种是最常见的使用互斥锁或者读写锁的方法: 第二种是比较符合Golang特色的方法,启动单个协程对map进行读写,当其他协程需要读写map时,通过channel向这个协程发送信号即可. 写了一个模拟程序对map中的一项进行读或者写,后台一直运行的协程阻塞的接受读写信号,并对map进行操作,但是读操作的时候没想好怎么返回这个值. 后来想到用传引用的方式,定义结构体,第一个

  • Go使用sync.Map来解决map的并发操作问题

    目录 前言 map 并发操作出现问题 sync.Map 解决并发操作问题 计算 map 长度 计算 sync.Map 长度 前言 在 Golang 中 map 不是并发安全的,自 1.9 才引入了 sync.Map ,sync.Map 的引入确实解决了 map 的并发安全问题,不过 sync.Map 却没有实现 len() 函数,如果想要计算 sync.Map 的长度,稍微有点麻烦,需要使用 Range 函数. map 并发操作出现问题 func main() { demo := make(ma

  • js遍历map javaScript遍历map的简单实现

    js遍历map javaScript遍历map的简单实现 var map = { "name" : "华仔", "realname":"刘德华" }; for (var key in map) { console.log("map["+key+"]"+map[key]); } 这样会把map给遍历掉,显示在浏览器上的控制器里. 以上这篇js遍历map javaScript遍历map的简单

  • ES6中Set和Map数据结构,Map与其它数据结构互相转换操作实例详解

    本文实例讲述了ES6中Set和Map数据结构,Map与其它数据结构互相转换操作.分享给大家供大家参考,具体如下: ES6 的 Set: ES6 提供了新的数据结构──Set.它类似于数组,但是成员的值都是唯一的,没有重复的值. Set 本身是一个构造函数,用来生成 Set 数据结构. Array和Set对比 都是一个存储多值的容器,两者可以互相转换,但是在使用场景上有区别.如下: ①Array的indexOf方法比Set的has方法效率低下 ②Set不含有重复值(可以利用这个特性实现对一个数组的

  • Go语言遍历map实现(访问map中的每一个键值对)

    map 的遍历过程使用 for range 循环完成,代码如下: scene := make(map[string]int) scene["route"] = 66 scene["brazil"] = 4 scene["china"] = 960 for k, v := range scene { fmt.Println(k, v) } 遍历对于Go语言的很多对象来说都是差不多的,直接使用 for range 语法即可,遍历时,可以同时获得键和值

  • mybatis-plus 查询传入参数Map,返回List<Map>方式

    目录 mybatis-plus 查询传入参数Map,返回List<Map> 1.mapper.xml 2.mapper.java 3.service 组装查询条件 mybatis-plus 基本使用 首先我们需要创建一个数据库表 然后创建一个Spring Boot项目 我们来演示几个基本的查询方法 再演示几个删除方法 再演示插入方法 mybatis-plus 查询传入参数Map,返回List<Map> 原因有时实体类属性不够用,又不想写自定义VO了,所以用map,这样直接返回前台用

  • 解决vue页面DOM操作不生效的问题

    现象: 使用Element UI渲染了一个树形结构,设计在鼠标移入每个节点是显示其中的操作按钮,效果如下: 下面是出错部分: 在新增节点后移入新增节点附近(图中是移入一级2),功能按钮的显示位置出现偏移 原因查找: 经过调试发现是在新增节点后,执行DOM操作获取节点时,取到的仍是之前的结构,新增的节点并未获取到. 原因分析: 猜测是vue使用的虚拟DOM,使得页面虽然已经渲染出来,但在Vue实例中让处在在虚拟DOM中,无法获取. 解决方法: 使用Vue.nextTick,看下官方材料: '在下次

  • Vue中component标签解决项目组件化操作

    一. 啰嗦几句 在vue项目组件化的过程中,遇到了一些问题,什么问题呢?就是在做一个多功能,多可用,多兼容的大组件的时候,发现在这个组件内部,实现了太多的if.for逻辑,包括大量的html元素,虽然说每段功能块都有批注,但是体积还是比较庞大,最近有些需求,需要将页面上的一大块筛选功能剥离开,形成单独的组件,统一数据渲染,统一组件管理,且这些功能无论是样式,或者是从结构来说,差异性都很大,所以考虑了以下几种开发方式: 1. 大容量单组件开发,渲染和传入的数据使用各种type.ctype判断 2.

  • 基于@RequestBody注解只能注入对象和map的解决

    目录 @RequestBody注解只能注入对象和map的问题 1.自定义一个适应于这种情况的注解@RequestJson 2.自定义RequestJsonHandlerMethodArgumentResolver 3.将上述配置应用到spring项目中 4.配置完成了,简单使用 @RequestBody注解的使用问题 先看一下@RequestBody的作用 个人总结: @RequestBody注解只能注入对象和map的问题 前后端分离开发模式下,前后端数据交互全部采用json,所以在后端在采用s

  • 解决Map集合使用get方法返回null抛出空指针异常问题

    目录 前言 空指针问题 原因 map.get,小心get出一个空指针 前言 1.Map里面只能存放对象,不能存放基本类型,例如int,需要使用Integer 2.Map集合取出时,如果变量声明了类型,会先进行拆箱,再进行转换. 空指针问题 如图,在程序执行到27行时,出现了空指针异常.按道理来讲,对于Map集合是有Key和Value的,Collection集合是只有Value.如果执行get()方法,当不存在key时,对应的应该返回null. map.get(s.charAt(i)); 因此 由

  • java8快速实现List转map 、分组、过滤等操作

    利用java8新特性,可以用简洁高效的代码来实现一些数据处理. 定义1个Apple对象: public class Apple { private Integer id; private String name; private BigDecimal money; private Integer num; public Apple(Integer id, String name, BigDecimal money, Integer num) { this.id = id; this.name =

随机推荐