• golang中map并发读写问题及解决方法


    一、map并发读写问题

    如果map由多协程同时读和写就会出现 fatal error:concurrent map read and map write的错误

    如下代码很容易就出现map并发读写问题

    func main(){

    c := make(map[string]int)
           go func() {//开一个协程写map
                for j := 0; j < 1000000; j++ {
                  c[fmt.Sprintf("%d", j)] = j
                }
           }()
           go func() {    //开一个协程读map
                 for j := 0; j < 1000000; j++ {
                     fmt.Println(c[fmt.Sprintf("%d",j)])
                 }
           }()

     time.Sleep(time.Second*20)

    }
     

    多个协程同时写也会出现fatal error: concurrent map writes的错误

    如下代码很容易出现map并发写的问题

    func main(){

    c := make(map[string]int)

    for i := 0; i < 100; i++ {
            go func() {  //开100个协程并发写map
                  for j := 0; j < 1000000; j++ {
                         c[fmt.Sprintf("%d", j)] = j
                  }
            }()
            }
           time.Sleep(time.Second*20)  //让执行main函数的主协成等待20s,不然不会执行上面的并发操作

    }

    二、出现问题的原因

    因为map为引用类型,所以即使函数传值调用,参数副本依然指向映射m, 所以多个goroutine并发写同一个映射m, 写过多线程程序的同学都知道,对于共享变量,资源,并发读写会产生竞争的, 故共享资源遭到破坏

    三、解决方法

    1、加锁

    (1)通用锁

    type Demo struct {

      Data map[string]string 

      Lock sync.Mutex

    }

    func (d Demo) Get(k string) string{

      d.Lock.Lock()

      defer d.Lock.UnLock()

      return d.Data[k]

    }

    func (d Demo) Set(k,v string) {

      d.Lock.Lock()

      defer d.Lock.UnLock()

      d.Data[k]=v

    }

    (2)读写锁

    type Demo struct {

      Data map[string]string 

      Lock sync.RwMutex

    }

    func (d Demo) Get(k string) string{

      d.Lock.RLock()

      defer d.Lock.RUnlock()

      return d.Data[k]

    }

    func (d Demo) Set(k,v string) {

      d.Lock.Lock()

      defer d.Lock.UnLock()

      d.Data[k]=v

    }

    2、利用channel串行化处理

  • 相关阅读:
    简单跟跟spring源码
    java.lang.UnsupportedOperationException mybatis
    通过自定义注解校验后台接口请求参数
    java的修饰符 public --> protected -->default --> private
    Ubuntu安装google-chrome
    git设置core.autocrlf
    时钟时间,系统cpu时间,用户cpu时间
    推荐-Everything搜索工具
    Ubuntu no such file or directory
    centos安装docker
  • 原文地址:https://www.cnblogs.com/williamjie/p/10053298.html
Copyright © 2020-2023  润新知