concurrent map使用
concurrent map使用
目录
- 概述
- 例子
1. 概述
- Go语言原生的map类型并不支持并发读写。concurrent-map提供了一种高性能的解决方案:通过对内部map进行分片,降低锁粒度,从而达到最少的锁等待时间(锁冲突)
- 在Go 1.9之前,go语言标准库中并没有实现并发map。在Go 1.9中,引入了sync.Map。新的sync.Map与此concurrent-map有几个关键区别。
- 标准库中的sync.Map是专为append-only场景设计的。因此,如果想将Map用于一个类似内存数据库,那么使用concurrent-map可能会更受益。
- sync.Map在读多写少性能比较好,否则并发性能很差
2. 例子
- 引用:
go test "github.com/orcaman/concurrent-map"
- 例子使用了部分方法,具体查看:concurrent_map_test.go
package mainimport ("encoding/json""fmt"cmap "github.com/orcaman/concurrent-map""github.com/prometheus/common/log""strconv"
)type Animal struct {name string
}func main() {m := cmap.New() // cmap.ConcurrentMapelephant := Animal{"elephant"}monkey := Animal{"monkey"}m.Set("elephant", elephant) // Set:添加元素m.Set("monkey", monkey)tmp, ok := m.Get("elephant") // Get:获取元素if ok == false {log.Error("ok should be true for item stored within the map.")}elephant, ok = tmp.(Animal) // 类型断言,转成指定类型,key为指针时需要加*if !ok {log.Error("expecting an element, not null.")}if elephant.name != "elephant" {log.Error("item was modified.")}if m.Has("elephant") == false { // Has:是否有这个元素log.Error("element exists, expecting Has to return True.")}m.Remove("monkey") // Remove:去除元素if m.Count() != 0 {log.Error("Expecting count to be zero once item was removed.")}monkey = Animal{"monkey"}m.Set("monkey", monkey)v, exists := m.Pop("monkey") // Pop:从map中获取这个元素并删除if !exists {log.Error("Pop didn't find a monkey.")}m1, ok := v.(Animal)if !ok || m1 != monkey {log.Error("Pop found something else, but monkey.")}if m.Count() != 100 { // Count: 计算map中元素个数log.Error("Expecting 100 element within map.")}if m.IsEmpty() == false { // IsEmpty:判断map是否为nillog.Error("new map should be empty")}// 插入100个元素for i := 0; i < 100; i++ {m.Set(strconv.Itoa(i), Animal{strconv.Itoa(i)})}counter := 0// Iterate over elements.for item := range m.IterBuffered() { // IterBuffered:获取缓冲迭代器,可用于for循环println(item.Val)val := item.Valname := item.Val.(Animal).namefmt.Println(name)if val == nil {log.Error("Expecting an object.")}counter++}m.Clear() // Clear:清空map// Insert 100 elements.for i := 0; i < 100; i++ {m.Set(strconv.Itoa(i), Animal{strconv.Itoa(i)})}// Iterate over elements.m.IterCb(func(key string, v interface{}) { // IterCb:遍历map,获取key,valuenum, ok := v.(Animal)fmt.Println(key,"---",num.name)if !ok {log.Error("Expecting an animal object")}counter++})items := m.Items() // Items:转换成map[string]interface{}if len(items) != 100 {log.Error("We should have counted 100 elements.")}m.Clear()m.Set("a", 1)m.Set("b", 2)j, err := json.Marshal(m) // 转换成json格式if err != nil {log.Error(err)}fmt.Println(j)keys := m.Keys() // Keys:获取map的key列表println(keys)animals := map[string]interface{}{"elephant": Animal{"elephant"},"monkey": Animal{"monkey"},}m.MSet(animals) // MSet:同时添加多个元素println(m.Count())dolphin := Animal{"dolphin"}whale := Animal{"whale"}tiger := Animal{"tiger"}lion := Animal{"lion"}cb := func(exists bool, valueInMap interface{}, newValue interface{}) interface{} {nv := newValue.(Animal)if !exists {return []Animal{nv}}res := valueInMap.([]Animal)return append(res, nv)}m.Set("marine", []Animal{dolphin})m.Upsert("marine", whale, cb) // Upsert:插入或更新元素m.Upsert("predator", tiger, cb)m.Upsert("predator", lion, cb)
}
concurrent map使用相关推荐
- go concurrent map writes map并发问题
go的map是并发不安全的,当同时启动多个goruotine对一个map进行读写操作时,会出现并发写问题fatal error: concurrent map writes 以下代码会出现:concu ...
- go map fatal error:concurrent map read and map write
go map fatal error:concurrent map read and map write golang中map并发读写问题及解决方法 go语言切片slice的线程协程安全问题 一.ma ...
- Go 学习笔记(67)— Go 并发安全字典 sync.Map
1. 并发不安全的 map Go 语言中的 map 在并发情况下,只读是线程安全的,同时读写是线程不安全的. 换句话说,在同一时间段内,让不同 goroutine 中的代码,对同一个字典进行读写操作是 ...
- go where 不等于_go基础之map迭代(四)
写在之前 在文章<go基础之map-写在前面(一)>的示例代码 for k, v := range m3 { fmt.Println(k, v)} 就是go的map的迭代方法,查看该代码的 ...
- Golang sync.Map原理
原生map的"先天不足" 对于已经初始化了的原生map,我们可以尽情地对其进行并发读: package mainimport ("fmt""math/ ...
- Go 1.9 sync.Map揭秘
Go 1.9 sync.Map揭秘 目录 [−] 有并发问题的map Go 1.9之前的解决方案 sync.Map Load Store Delete Range sync.Map的性能 其它 在Go ...
- golang中的sync.Map
Go 语言中的 map 在并发情况下,只读是线程安全的,同时读写线程不安全. 下面来看下并发情况下读写 map 时会出现的问题,代码如下: package mainfunc main() {//创建一 ...
- golang中map并发读写问题及解决方法
这是一个创建于 2017-03-05 06:02:54 的文章,其中的信息可能已经有所发展或是发生改变. 一.map并发读写问题 如果map由多协程同时读和写就会出现 fatal error:conc ...
- Go中的Map实现机制
Map大合集 1. 原理 2.1 哈希冲突 2.2 Map底层原理剖析 2.2.1 初始化 2.2.2 写入数据 2.2.3 查找数据 2.2.4 扩容 2.2.5 迁移 翻倍扩容 等量扩容 2.3 ...
最新文章
- DL645规约学习笔记-一帧数据解释
- aix服务器屏幕显示被锁住了,AIX恢复密码过程总结
- 第四节:EasyUI的一些操作
- 4)Thymeleaf th:each 循环迭代与 th:if、th:switch 条件判断
- swift5 修改Accessibility order读取的顺序
- MySQL 递归查询
- 常见的web网站攻击类型
- Google Chrome显示粉红色屏幕
- Java里面的Lambda表达式
- 第一篇 香橙派刷机和开发环境准备(Armbian版)
- wkhtmltopdf参数详解
- 学习c语言神经网络编程软件
- world wind java sdk_World wind Java SDK安装开发测试
- 视频剪辑自学怎么入门?借助这款软件可以达到意想不到的效果
- 现代企业管理笔记——控制
- 计算机相关先锋队名称,励志团队名称和口号大全_团队励志队名口号大全
- 数据库手工注入中的闭合
- 教资教招笔记整理(二)
- 高等数学——柱面与旋转曲面
- 专家揭秘:补充叶黄素视力毫无改善,原因何在?
热门文章
- 企业运维笔试考题(1)
- 6月共处理钓鱼网站8186个:非CN域名达8029个
- CodeForces - 336D Vasily the Bear and Beautiful Strings(dp+组合数学)
- CodeForces - 1323D Present(思维+数学)
- POJ - 3080 Blue Jeans(暴力+KMP)
- HDU - 5015 233 Matrix(矩阵快速幂)
- C++读图片——Mac下对于bmp文件读写读取过大的解决方案
- python 协程、进程、线程_Python 中的进程、线程、协程
- linux基础命令chown,Linux常用命令及组件:chown和chmod
- git 删除本地仓库中的分支_本地 Git 仓库与 GitHub 关联