zoukankan      html  css  js  c++  java
  • golang 中map的并发安全

    golang 自带的map不是并发安全的,并发读写会报错:

    fatal error: concurrent map read and map write

    一般的解决方式是加锁,控制互斥。

    1.加锁的map

    如下代码所示:

    package main
    
    import (
        "fmt"
        "sync"
        "time"
    )
    
    type Map struct {
        m map[int]int
        sync.RWMutex
    }
    
    
    func(this *Map) Get(key int) int {
        this.RLock()
        defer this.RUnlock()
        
        v := this.m[i]
        return v
    }
    
    func(this *Map) Set(k, v int) {
        this.Lock()
        defer this.Unlock()
        
        this.m[k] = v
    }
    
    func main(){
    
        newMap := &Map{m: make(map[int]int)}
        
        for i := 0; i< 10000; i<++ {
            go newMap.Set(i, i)
        }
        
        for i := 0; i< 10000; i<++ {
            go fmt.Println(i, newMap.Get(i))
        }
        
        time.Sleep(time.Second)
    }
    

    2.使用sync.Map

    从1.9版本开始,sync包中提供了并发安全的map,也就是sync.Map,其内部实现上已经做了互斥处理。

    使用举例如下:

    例子中,使用Store设置kv,使用Load读取kv,使用Delete删除kv。

    package main
    
    import (
            "fmt"
            "sync"
    )
    
    type Counter struct {
            count int
    }
    
    func main() {
            var m sync.Map
    
            m.Store("a", 1)
            m.Store("b", 2)
    
            counter := &Counter{count:2}
            m.Store("c", counter)
    
            fmt.Println("m:", m)
    
            v, ok := m.Load("a")
            fmt.Println("a v:", v, ", ok:", ok)
            fmt.Printf("a type: %T
    ", v)
    
            v, ok = m.Load("b")
            fmt.Println("b v:", v, ", ok:", ok)
    
            v, ok = m.Load("c")
            fmt.Println("c v:", v, ", ok:", ok)
            fmt.Printf("c type %T
    ", v)
            vc,_ := v.(*Counter)
            vc.count += 1
    
    
            fmt.Println("================")
            v, ok = m.Load("c")
            fmt.Println("c v:", v, ", ok:", ok)
    
            m.Delete("d")
    }
    

    output:

    m: {{0 0} {{map[] true}} map[a:0xc00000e028 b:0xc00000e030 c:0xc00000e038] 0}
    a v: 1 , ok: true
    a type: int
    b v: 2 , ok: true
    c v: &{2} , ok: true
    c type *main.Counter
    ================
    c v: &{3} , ok: true

    3.参考

    sync.Map

    Just try, don't shy.
  • 相关阅读:
    PostMan使用教程(1)
    测试工作量的评估方法
    Jmeter之Bean shell使用(二)
    centos7 编译安装redis
    Centos7 安装mariadb
    Centos7 安装使用virtualenvwrapper
    Centos7安装python3.6
    linux基础命令2
    linux基础命令
    linux目录结构
  • 原文地址:https://www.cnblogs.com/lanyangsh/p/14456177.html
Copyright © 2011-2022 走看看