1. sync.Map

1.1. map并发不安全

go1.6以后map有了并发的安全检查,所以如果在并发环境中读写map就会报错

  1. func unsafeMap() {
  2. // 创建一个map对象
  3. m := make(map[int]int)
  4. go func() {
  5. for {
  6. // 尝试读取数据
  7. _ = m[1]
  8. }
  9. }()
  10. go func() {
  11. for {
  12. // 尝试写入数据
  13. m[2] = 2
  14. }
  15. }()
  16. // 阻塞
  17. select {}
  18. }
  19.  
  20. // output
  21. // fatalerror: concurrent map read and map write

1.2 安全map

并发环境下面使用安全的map

1.2.1 自定义结构体

  1. // 通过内嵌读写锁的方式,保证我们使用map的安全性
  2. type MyMap struct{
  3. sync.RWMutex
  4. m map[string]int // 需要一个并发的map[string]int类型
  5. }
  6.  
  7. // 封装一个创建map对象的方法
  8. func NewMyMap()*MyMap{
  9. smp:=new(MyMap)
  10. smp.m = make(map[string]int)
  11. return smp
  12. } 

注意:我们定义使用什么类型的map,那么就内置什么类型的map

1.2.2 sync.Map

go1.9以后sync包中加入了安全的map对象,,syn.Map不支持普通的map操作,需要使用sync.Map提供的api使用

    • 创建sync.Map对象

      1. //1. 不需要通过map的方式进行创建,通过声明的方式或者new创建即可
      2. var smap sync.Map
      3.  
      4. //2. 通过new的方式创建
      5. smap:=new(sync.Map)
    • sync.Map 存储数据store方法

      1. //func (m *Map) Store(key, value interface{})
      2. // key,value 都是接口类型,可以存储任何类型的数据
      3. smap.Store(1,"MrSun")
    • sync.Map读取数据

      1. // func (m *Map) Load(key interface{}) (value interface{}, ok bool)
      2. // key: 键,value: 如果数据存在则返回对应的值,不存在则返回nil,ok: 表示值知否被找到
      3. // 记得对数据断言处理
      4. val,ok:=smap.Load(1)
    • sync.Map,存在则读取,不存在存储

      1. // func (m *Map) LoadOrStore(key, value interface{}) (actual interface{}, loaded bool)
      2. // key,value: 要存储的key与value
      3. //actual: 如果存在则返回存在的值,如果不存在则存储并返回存储的值
      4. // laoded: 如果数据存在,则true,如果数据不存在则false
      5. actual, loaded := smap.LoadOrStore(1, "MrSun")
    • sync.Map 遍历

      1. // 创建map
      2. smap:=new(sync.Map)
      3. smap.LoadOrStore(1, "MrSun")
      4. smap.LoadOrStore(2, "hello")
      5. smap.LoadOrStore(3, "golang")
      6. smap.LoadOrStore(4, "bilili")
      7. //func (m *Map) Range(f func(key, value interface{}) bool)
      8. // 用户处理数据的回调函数,回调函数的参数是key,value,返回值是bool
      9. smap.Range(func(key, value interface{}) bool {
      10. smap.Store(5,"heihei")
      11. fmt.Println(key,value)
      12. return true
      13. }) 
      14.  
      15. // 注意:Range方法遍历的是map的副本
    1. sync.Map 数据删除
    1. // func (m *Map) Delete(key interface{})
    2. // key: 要删除数据的key值
    3. smap.Delete(1)

1.2.3 sync.Map与内置读写锁性能对比

  • 4核心以前内置的读写锁map性能要高

  • 4核心后,sync.Map 性能要高

  • sync.Map 性能稳定

1.2.4 sync.Map使用场景

The Map type is optimized for two common use cases:

  1. when the entry for a given key is only ever written once but read many times, as in caches that only grow.

  2. when multiple goroutines read, write, and overwrite entries for disjoint sets of keys. In these two cases, use of a Map may significantly reduce lock contention compared to a Go map paired with a separate Mutex or RWMutex.

  • 写少读多的情况

  • 多goroutine,读、写、复写 不同数据的情况 【没遇到过】

  • 多核心情况使用

建议:没有特别要求的情况,两者都可以,go1.9以后建议直接使用sync.Map

1.2.5 sync.Map源码剖析

sync.Map

2. Concurrent Map

并发安全map,类似java下面的java.util.ConcurrentHashMap,适合读写都相对比较频繁的情况

2.1 基本原理

采用分段锁机制,从而提高并发安全的性能

2.2 concurrent map下载

  1. # github 星标 最高的一个
  2. go get "github.com/orcaman/concurrent-map"

2.2 基本使用

不同的第三方包模块使用API都不一样,使用那个模块需要查看对应模块的文档

  1. import "github.com/orcaman/concurrent-map"
  2.  
  3. func concurrentMap() {
  4. mp:=cmap.New()
  5. // 存储值,key只能是string类型,value可以是任意类型
  6. mp.Set("1","hello")
  7. mp.Set("2","golang")
  8. //val: 如果存在则返回值,不存在则返回nil
  9. // ok: 表示值如果存在则是true,如果不存在则是false
  10. val,ok:=mp.Get("2")
  11. if ok{
  12. fmt.Println(val.(string))
  13. }
  14. mp.Remove("1")
  15. _,ok=mp.Get("1")
  16. if !ok{
  17. fmt.Println("data is not exist")
  18. }
  19. }

sync.Map与Concurrent Map的更多相关文章

  1. Qt之Concurrent Map和Map-Reduce

    简述 QtConcurrent::map().QtConcurrent::mapped()和QtConcurrent::mappedReduced()函数在一个序列中(例如:QList或QVector ...

  2. golang fatal error: concurrent map read and map write

    调试程序的时候,为了打印map中的内容 ,直接 使用seelog 的方法打印 map中的内容到日志,结果出现 “concurrent map read and map write”的错误,导致程序异常 ...

  3. CXF2.7整合spring发布webservice,返回值类型是Map和List<Map>类型

    在昨天研究了发布CXF发布webservice之后想着将以前的项目发布webservice接口,可是怎么也发布不起来,服务启动失败,原来是自己的接口有返回值类型是Map. 研究了一番之后,发现: we ...

  4. Map接口,Map.Entry,hashMap类,TreeMap类,WeakHashMap。

    Collection接口之前接触过,每次保存的对象是一个对象,但是在map中保存的是一对对象,是以key->value形式保存的. 定义: public interface Map<K,V ...

  5. Map java中的map 如何修改Map中的对应元素

    Map java中的map 如何修改Map中的对应元素 Map以按键/数值对的形式存储数据,和数组非常相似,在数组中存在的索引,它们本身也是对象.         Map的接口         Map ...

  6. Java-map-第一题 (Map)利用Map,完成下面的功能: 从命令行读入一个字符串,表示一个年份,输出该年的世界杯冠军是哪支球队。如果该 年没有举办世界杯,则输出:没有举办世界杯。 附:世界杯冠军以及对应的夺冠年份,请参考本章附录。 附录

    第一题 (Map)利用Map,完成下面的功能: 从命令行读入一个字符串,表示一个年份,输出该年的世界杯冠军是哪支球队.如果该 年没有举办世界杯,则输出:没有举办世界杯. 附:世界杯冠军以及对应的夺冠年 ...

  7. 另一种遍历Map的方式: Map.Entry 和 Map.entrySet()

    源网址: http://blog.csdn.net/mageshuai/article/details/3523116 今天看Think in java 的GUI这一章的时候,里面的TextArea这 ...

  8. 迭代输出Map和List<Map<String,Object>>的方法

    一.Map<String,Object> String:key的类型 Object:value的类型,value可能是String,或者int类型,什么类型都可以 对于Map接口来说,本身 ...

  9. Java集合Map接口与Map.Entry学习

    Java集合Map接口与Map.Entry学习 Map接口不是Collection接口的继承.Map接口用于维护键/值对(key/value pairs).该接口描述了从不重复的键到值的映射. (1) ...

随机推荐

  1. MSSQL - 最佳实践 - 使用SSL加密连接

    MSSQL - 最佳实践 - 使用SSL加密连接 author: 风移 摘要 在SQL Server安全系列专题月报分享中,往期我们已经陆续分享了:如何使用对称密钥实现SQL Server列加密技术. ...

  2. 安装包RPM包或源码包

    RPM工具 # mount /dev/cdrom /mnt     挂载光盘 # rpm     软件包管理器 -i     安装(需要安装包完整名称) -v    可视化 -h    显示安装进度 ...

  3. Shell—详解$( )、$(( ))、``与${ }的区别

    https://www.jianshu.com/p/2237f029c385 https://www.cnblogs.com/chenpython123/p/11052276.html https:/ ...

  4. cinder安装与配置

    cinder是openstack中提供块存储服务的组件,主要是为虚拟机实例提供虚拟磁盘. 通过某种协议(SAS,SCSI,SAN,iSCSI等)挂接裸硬盘,然后分区.格式化创建的文件,或者直接使用裸硬 ...

  5. React-Native踩坑记录二

    1.Image组件的borderRadius画圆有平台兼容性问题,在IOS下会失效 解决方法有几种 (1)在外面包裹一层View,对View组件使用borderRadius就可以了,这是我的做法 (2 ...

  6. PHP中使用date获取上月最后一天出现的问题

    上次做项目时,发现一个问题,这里记录一下: 问题: 在使用date函数获取上一个月最后一天或下个月最后一天时,如果当前日期是31号,获取的数据有问题. // 2019-12-01 正确应该是 2019 ...

  7. 数据库性能提升利器—Mycat数据切分

    一.前言      数据库是每个系统都不可缺少的东西,里面记录了系统各种数据资料.但是如今的数据膨胀的时代,数据库性能不能满足我们的需要了.所以我们要对数据库进行强化,就用到了Mycat. 二.何为数 ...

  8. 关于List和String有意思的几个应用

      关于List和String有意思的几个应用 1. List:all_equal 功能:验证列表中的所有元素是否是都一样的. 解析:该技巧是使用[1:] 和 [:-1] 来比较所给定列表中的所有元素 ...

  9. 从零开始ant-design-vue-pro开发笔记(一)

    开始 从这里开始是用ant-design-vue组件写ant-design-vue-pro这个后台项目实现步骤的从零开始搭建的过程,视频地址,它采用了ant-desgin-vue的组件库作为素材开发, ...

  10. Dubbo学习系列之十一(Dashboard+Nacos规则推送)

    中国武术,门派林立,都是号称多少代的XXX传人,结果在面对现代武术时,经常被KO秒杀,为啥,光靠宣传和口号撑门面,终究是靠不住,必须得有真货 ,得经得住考验,所以不能只说Sentinel有多好,也得给 ...