精华内容
下载资源
问答
  • go sync.Map使用和介绍

    万次阅读 2018-08-28 15:14:29
    sync.Map使用和介绍 首先看下该map的使用: _** package main import ( “sync” “fmt” ) func main() { //开箱即用 var sm sync.Map //store 方法,添加元素 sm.Store(1,”a”) //Load 方法,...

    sync.Map使用和介绍

    1、首先看下该sync.Map的使用:

    package main
    import (
        "sync"
        "fmt"
    )
    
    func main() {
        //开箱即用
        var sm sync.Map
        //store 方法,添加元素
        sm.Store(1,"a")
        //Load 方法,获得value
        if v,ok:=sm.Load(1);ok{
            fmt.Println(v)
        }
        //LoadOrStore方法,获取或者保存
        //参数是一对key:value,如果该key存在且没有被标记删除则返回原先的value(不更新)和true;不存在则store,返回该value 和false
        if vv,ok:=sm.LoadOrStore(1,"c");ok{
            fmt.Println(vv)
        }
        if vv,ok:=sm.LoadOrStore(2,"c");!ok{
            fmt.Println(vv)
        }
        //遍历该map,参数是个函数,该函数参的两个参数是遍历获得的key和value,返回一个bool值,当返回false时,遍历立刻结束。
        sm.Range(func(k,v interface{})bool{
            fmt.Print(k)
            fmt.Print(":")
            fmt.Print(v)
            fmt.Println()
            return true
        })
    }

    运行结果:

    a
    a
    c
    1:a
    2:c

    2、利用传统的sync.RWMutex+Map 实现并发安全的map:

    var rwmap = struct{
        sync.RWMutex
        m map[string]string
    }{m: make(map[string]sring)}

    读数据时候,读锁锁定:

    rwmap.RLock()
    value:= rwmap.m["key"]
    rwmap.RUnlock()
    fmt.Println("key:", value)

    写数据的时候,写锁锁定:

    rwmap.Lock()
    rwmap.m["key"]="value"
    rwmap.Unlock()

    3、两种map的性能对比:
    下面是有人做的两种map性能对比图:
    这里写图片描述
    可见随着cpu核心数的增加、并发加剧,这种读写锁+map的方式性能在不停的衰减,并且在核数为4的时候出现了性能的拐点;而sync.Map虽然性能不是特别好,但是相对比较平稳。
    4、sync.Map 源码解析
    源码位于:src\sync\map.go
    首先查看一下sync.Map的数据结构:

      type Map struct {
        // 该锁用来保护dirty
        mu Mutex
        // 存读的数据,因为是atomic.value类型,只读类型,所以它的读是并发安全的
        read atomic.Value // readOnly
        //包含最新的写入的数据,并且在写的时候,会把read 中未被删除的数据拷贝到该dirty中,因为是普通的map存在并发安全问题,需要用到上面的mu字段。
        dirty map[interface{}]*entry
        // 从read读数据的时候,会将该字段+1,当等于len(dirty)的时候,会将dirty拷贝到read中(从而提升读的性能)。
        misses int
    }
    

    read的数据结构是:

    type readOnly struct {
        m  map[interface{}]*entry
        // 如果Map.dirty的数据和m 中的数据不一样是为true
        amended bool 
    }

    entry的数据结构:

    type entry struct {
        //可见value是个指针类型,虽然read和dirty存在冗余情况(amended=false),但是由于是指针类型,存储的空间应该不是问题
        p unsafe.Pointer // *interface{}
    }

    Delete
    首先来看delete方法

    func (m *Map) Delete(key interface{}) {
        read, _ := m.read.Load().(readOnly)
        e, ok := read.m[key]
        //如果read中没有,并且dirty中有新元素,那么就去dirty中去找
        if !ok && read.amended {
            m.mu.Lock()
            //这是双检查(上面的if判断和锁不是一个原子性操作)
            read, _ = m.read.Load().(readOnly)
            e, ok = read.m[key]
            if !ok && read.amended {
                //直接删除
                delete(m.dirty, key)
            }
            m.mu.Unlock()
        }
        if ok {
        //如果read中存在该key,则将该value 赋值nil(采用标记的方式删除!)
            e.delete()
        }
    }
    func (e *entry) delete() (hadValue bool) {
        for {
            p := atomic.LoadPointer(&e.p)
            if p == nil || p == expunged {
                return false
            }
            if atomic.CompareAndSwapPointer(&e.p, p, nil) {
                return true
            }
        }
    }

    Store
    新加元素

    func (m *Map) Store(key, value interface{}) {
        // 如果m.read存在这个key,并且没有被标记删除,则尝试更新。
        read, _ := m.read.Load().(readOnly)
        if e, ok := read.m[key]; ok && e.tryStore(&value) {
            return
        }
        // 如果read不存在或者已经被标记删除
        m.mu.Lock()
        read, _ = m.read.Load().(readOnly)
        if e, ok := read.m[key]; ok {
        //如果entry被标记expunge,则表明dirty没有key,可添加入dirty,并更新entry
            if e.unexpungeLocked() { 
                //加入dirty中
                m.dirty[key] = e
            }
            //更新value值
            e.storeLocked(&value) 
            //dirty 存在该key,更新
        } else if e, ok := m.dirty[key]; ok { 
            e.storeLocked(&value)
            //read 和dirty都没有,新添加一条
        } else {
         //dirty中没有新的数据,往dirty中增加第一个新键
            if !read.amended { 
                //将read中未删除的数据加入到dirty中
                m.dirtyLocked() 
                m.read.Store(readOnly{m: read.m, amended: true})
            }
            m.dirty[key] = newEntry(value) 
        }
        m.mu.Unlock()
    }
    
    //将read中未删除的数据加入到dirty中
    func (m *Map) dirtyLocked() {
        if m.dirty != nil {
            return
        }
        read, _ := m.read.Load().(readOnly)
        m.dirty = make(map[interface{}]*entry, len(read.m))
        //read如果较大的话,可能影响性能
        for k, e := range read.m {
        //通过此次操作,dirty中的元素都是未被删除的,可见expunge的元素不在dirty中
            if !e.tryExpungeLocked() {
                m.dirty[k] = e
            }
        }
    }
    //判断entry是否被标记删除,并且将标记为nil的entry更新标记为expunge
    func (e *entry) tryExpungeLocked() (isExpunged bool) {
        p := atomic.LoadPointer(&e.p)
        for p == nil {
            // 将已经删除标记为nil的数据标记为expunged
            if atomic.CompareAndSwapPointer(&e.p, nil, expunged) {
                return true
            }
            p = atomic.LoadPointer(&e.p)
        }
        return p == expunged
    }
    //对entry 尝试更新
    func (e *entry) tryStore(i *interface{}) bool {
        p := atomic.LoadPointer(&e.p)
        if p == expunged {
            return false
        }
        for {
            if atomic.CompareAndSwapPointer(&e.p, p, unsafe.Pointer(i)) {
                return true
            }
            p = atomic.LoadPointer(&e.p)
            if p == expunged {
                return false
            }
        }
    }
    //read里 将标记为expunge的更新为nil
    func (e *entry) unexpungeLocked() (wasExpunged bool) {
        return atomic.CompareAndSwapPointer(&e.p, expunged, nil)
    }
    //更新entry
    func (e *entry) storeLocked(i *interface{}) {
        atomic.StorePointer(&e.p, unsafe.Pointer(i))
    }

    可见,每次操作先检查read,因为read 并发安全,性能好些;read不满足,则加锁检查dirty,一旦是新的键值,dirty会被read更新。
    Load
    加载方法,查找key。

    func (m *Map) Load(key interface{}) (value interface{}, ok bool) {
        //因read只读,线程安全,先查看是否满足条件
        read, _ := m.read.Load().(readOnly)
        e, ok := read.m[key]
        //如果read没有,并且dirty有新数据,那从dirty中查找,由于dirty是普通map,线程不安全,这个时候用到互斥锁了
        if !ok && read.amended {
            m.mu.Lock()
            // 双重检查
            read, _ = m.read.Load().(readOnly)
            e, ok = read.m[key]
            // 如果read中还是不存在,并且dirty中有新数据
            if !ok && read.amended {
                e, ok = m.dirty[key]
                // mssLocked()函数是性能是sync.Map 性能得以保证的重要函数,目的讲有锁的dirty数据,替换到只读线程安全的read里
                m.missLocked()
            }
            m.mu.Unlock()
        }
        if !ok {
            return nil, false
        }
        return e.load()
    }
    //dirty 提升至read 关键函数,当misses 经过多次因为load之后,大小等于len(dirty)时候,讲dirty替换到read里,以此达到性能提升。
    func (m *Map) missLocked() {
        m.misses++
        if m.misses < len(m.dirty) {
            return
        }
        //原子操作,耗时很小
        m.read.Store(readOnly{m: m.dirty})
        m.dirty = nil
        m.misses = 0
    }

    源码用的是1.9版本,通过阅读源码我们发现sync.Map是通过冗余的两个数据结构(read、dirty),实现性能的提升。为了提升性能,load、delete、store等操作尽量使用只读的read;为了提高read的key击中概率,采用动态调整,将dirty数据提升为read;对于数据的删除,采用延迟标记删除法,只有在提升dirty的时候才删除。

    展开全文
  • Map使用Iterator遍历输出

    万次阅读 2016-07-26 22:31:03
    Map使用Iterator遍历输出

    java中的map有好几种输出方法,本篇博客只讲其中的迭代器输出

    代码如下

    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.Map;
    
    public class MapOutput {
    
    	/**
    	 * @param args
    	 */
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    		Map<Integer,String> map = new HashMap<Integer,String>();
    		map.put(1, "aaa");
    		map.put(2, "bbb");
    		map.put(3, "ccc");
    		map.put(4, "ddd");
    		
    		Iterator<Map.Entry<Integer,String>> it=map.entrySet().iterator();
    		while(it.hasNext()){
    			Map.Entry<Integer,String> entry=it.next();
    			System.out.println("key="+entry.getKey()+","+"value="+entry.getValue());
    		}
    		
    
    	}
    
    }
    

    输出结果如下

    key=1,value=aaa
    key=2,value=bbb
    key=3,value=ccc
    key=4,value=ddd

    展开全文
  • map使用return false无法退出循环

    千次阅读 2019-11-07 14:59:24
    map使用return false无法退出循环 解决方法: 使用for替换map,for可以使用return false退出循环

    map使用return false无法退出循环

    解决方法:

    使用for替换map,for可以使用return false退出循环

    展开全文
  • json对象作为map使用

    千次阅读 2018-08-13 15:31:27
    json对象作为map使用    原理就是Json对象里还是放Json对象  可以 :  var obj = {};  obj.id = info.id; //这里id是key 的名称  也可以:  var obj = {};  obj["id"] = info.id; //这里id也是...

    json对象作为map使用
            
        原理就是Json对象里还是放Json对象
        可以 :
        var obj = {};
        obj.id = info.id; //这里id是key 的名称

        也可以:
        var obj = {};
        obj["id"] = info.id; //这里id也是key 的名称

         

        甚至可以:
        obj[id] = info.id;

        //这里的id就是变量了,可以赋值 ,比如以遍历对象的id准确的值作为key
        
        var cache = {};
        var info = {id: "19", name: "ddddd", pid: "4", check: "true", child:"25"};
        
        var node = {};
        node.id = info.id;   // node.id = info.id; 等同于 node["id"] = info.id;
        node.name = info.name;
        node.child = info.child;
        
        cache[info.id] = node;
        
        cache输出:
        {19: {…}}
        
        19:{id: "19", name: "ddddd", child: "25"}

        

    map就很方便了,和java的map很像 ,具体没有实战用过 等学习了再补充在下面
        var map = new Map();
        map.set("19",{id: "19", name: "ddddd", child: "25"});

        

     

    展开全文
  • Scala中的Map使用例子

    万次阅读 2016-12-27 22:09:46
    Map结构是一种非常常见的结构,在各种程序语言都有对应的api,由于Spark的底层语言是Scala,所以有必要来了解下Scala中的Map使用方法。 (1)不可变Map 特点: api不太丰富 如果是var修饰,引用可变,...
  • java map 使用详解

    万次阅读 2012-05-19 18:56:48
    import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.Set;...public class KeysetTest { ...//map使用  @SuppressWarnings("unchecked") public static void main(Stri
  • Java中Map使用/渠道ID

    万次阅读 2018-03-19 14:58:01
    Java中Map使用/渠道ID /** * 渠道ID */ private static final Map&lt;String, String&gt; channelIdAndKey = new HashedMap() { { List&lt;String&gt; channelIDs = Arrays.asList(...
  • java ImmutableMap使用

    万次阅读 2018-12-14 08:49:24
    ImmutableMap:一个不可变集合  java中的Immutable对象: 简单地说,如果一个对象实例不能被更改就是一个Immutable的对象,Java SDK提供的大量值对象,比如String等都是Immutable的对象。 创建ImmutableMap: ...
  • c++ map使用

    千次阅读 2014-01-21 16:56:47
    最近学习中需要用到stl map和vector,所以此处就整理了下,把它封装成一个类,方便自己以后使用,后面会加上vector的使用 map_class.h代码: #ifndef MAP_CLASS_H #define MAP_CLASS_H /* C++ Maps是一种关联式...
  • erlang map 使用

    千次阅读 2016-01-28 00:14:20
    主要是遇到 Map匹配的问题,所以顺便回忆一下 Erlang 中的映射组 Map,在其它语言中被称作 Hash 哈希或者 Dict 字典。 Erlang 从 R17 版本开始支持映射组 创建映射组 Erlang 中的映射组用结构 #{} 表示,创建...
  • 什么时候使用Map? 当存在映射关系时 比如:每个学生对应一个地址 */package com.Map; import java.util.*; class StudentHM //先定义一个学生类 { private String name; private int age; public ...
  • C++ map使用详解

    千次阅读 2015-09-13 14:04:20
    使用map简介包含头文件#include <map> map使用红黑树实现的。她的访问,查找和删除操作的复杂度都是O(logn).
  • map使用方法

    万次阅读 2015-04-22 22:21:34
    #include #include #include #include using namespace std;...//创建一个map(键=>值)容器 //m['键1'] = "值1"; srand(unsigned int(time(NULL))); for (int i = 0; i ; i++)//初始化 m[i] = ra
  • nginx中map使用方法

    千次阅读 2019-06-19 17:43:51
    本文为转载文章 ... map 指令介绍: map 指令是由 ngx_http_map_module 模块提供的,默认情况下安装 ...map 的主要作用是创建自定义变量,通过使用 nginx 的内置变量,去匹配某些特定规则,如果匹配成功则设置某...
  • SourceMap 使用教程

    千次阅读 2018-07-18 14:20:12
    真的是一个很好用的bug监控费服务,众多大佬公司都在使用。   1. 前言 SourceMap 一个存储源代码与编译代码对应位置映射的信息文件 在前端的工作中主要是用来解决以下三个方面出现的 debug 问题: a. 代码...
  • golang sync.Map 使用

    千次阅读 2019-04-20 13:48:02
    自1.9版本以后提供了sync.Map,支持多线程并发读写,比之前的加锁map性能要好一点。 提供一下几个方法: type Map //删除指定key func (m *Map) Delete(key interface{}) //查询指定key func (m *Map) Load...
  • ES6之Map使用

    千次阅读 2018-11-14 21:20:53
    这种集合,将key映射到指定的值上,在不同的编程语言中具有不同的名称,通常称为字典或Map。 在JavaScript中如何有效地管理这种定位呢?一种传统的定位方法是利用对象是属性名和属性值的特性。   创建如下字典:...
  • kubernetes系列之ConfigMap使用方式

    千次阅读 2020-08-10 09:31:08
    mysql容器重要的文件有两部分,一部分为存储数据文件,一部分为配置文件my.cnf,存储数据可以用持久存储实现和容器的分离解耦,配置文件也能够实现和容器的分离解耦,也就是说mysql容器能够直接读取并使用预先配置好的...
  • Golang线程安全Map:sync.Map使用小结

    千次阅读 2019-03-04 11:13:23
    转载自: https://blog.csdn.net/u010230794/article/details/82143179 ... sync.Map使用: package main import ( "sync" "fmt" ) func main() { //开箱即用 var sm sync.Map ...
  • Java 各类Map使用场景之Map概述

    千次阅读 2017-04-05 14:40:22
    Map隶属java.util包,util包是包含了collection框架,遗留的collection类、时间模型、日期和时间、国际化和各种工具类(字符串标记生成器、随机数生成器和位数组.Map在java中是一个接口。取代了Dictionary类,后者...
  • Vue Baidu Map使用

    千次阅读 2018-12-11 17:01:54
    百度地图官方提供的是常规&amp;lt;script&amp;gt;标签引入的方法。要想将百度地图引入Vue中,...这样,在页面中就可以像常规的页面那样使用百度地图了。需要为容器&amp;lt;div&amp;gt;设置一个id属...
  • C++ unordered_map使用问题

    千次阅读 2019-01-13 17:02:02
    第一次使用unordered_map 最开始引入#include&lt;unordered_map&gt;,但是报错:[Error] 'unordered_map' was not declared in this scope 解决办法: 引入#include&lt;tr1/unordered_map&gt;...
  • C++ map使用详细版

    千次阅读 2018-08-21 20:25:41
    经过几个小时的学习以及测试,map的基本结构是熟悉,但是要想达到灵活运用恐怕还需要进一步练习。以后在涉及到C++中的哈希表时候,用map做代替. 可以横向对比一下vector,大同小异。 1 定义:键值一一对应,key不...
  • map使用不存在的下标

    万次阅读 2019-02-20 19:17:51
    当用访问map存在的下标时,大家都指的答案。当访问不存在的下标时,又会发生什么呢?来看下 #include &lt;iostream&gt; #include &lt;map&gt; #include &lt;string&gt; using namespace ...
  • k8s-ConfigMap使用

    万次阅读 2018-09-14 09:05:04
    ConfigMap的用处: 1. 生成为容器内的环境变量 2. 设置容器启动的命令参数 3. volume形式挂载成容器内的文件或目录 1.通过yml文件创建一个configmap: 2. 通过命令行创建 kubectl create conf...
  • Lambda 的 forEach表达式用起来很爽啊,最近开发中用来遍历了一下Map,结果就翻车了......大致场景如下: public static void main(String[] args) { HashMap<String,String> map = new HashMap<>(); ...
  • 一个hash_map使用错误

    千次阅读 2006-07-20 16:44:00
    一个hash_map使用错误g++的 hash_map 运行不起来#include #include using namespace std;using namespace __gnu_cxx;namespace __gnu_cxx{ template { size_t operator()(const string& s) const 
  • 最近新项目需要做一个用到瓦片地图的游戏,第一想法就是要用Tilemap,之前Unity没有自带的Tilemap,都是第三方插件。知道去年2017.2发布,就有自带的Tilemap啦!将Unity升级到2017.3.1,Tilemap的基本操作,其实API...
  • ImmutableMap 的作用就是:可以让java代码也能够创建一个对象常量映射,来保存一些常量映射的键值对。 分析以下情景,来具体讨论这个的好处。 以下是在js前台的代码,假设现在有需求如下: 根据数据库存的某个key...
  • std 之 map 使用总结

    千次阅读 2013-05-17 14:00:12
    map 是一种关联容器, 提供一对一的关联, 关联的形式为: KEY----VALUE 关键字不重复。multimap与map类似,但是允许关键字重复 即:关键字和与之对应的值 关键字起到索引的作用, 在map中查找记录 就是根据...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 101,258
精华内容 40,503
关键字:

map使用