map并发安全问题及解决办法

package main

import (
   "fmt"
   "sync"
)

func main() {
   m := map[int64]int64{0: 0}
   waitGroup := sync.WaitGroup{}

   for i := 0; i < 1000; i++ {
      waitGroup.Add(1)
      go func(i int) {
         m[0]++
         waitGroup.Done()
      }(i)
   }

   waitGroup.Wait()

   fmt.Println(m)
}

// ========== 总结 ========== //
// 1、map不是并发安全的,多个协程对同一个map进行操作可能会出现数据竞争问题,如上面的代码可能出现m[0]最终值小于1000的情况,
//    也有可能因为同时写入map导致程序出错(fatal error: concurrent map writes)。



package main

import (
   "fmt"
   "sync"
)

func main() {
   m := map[int64]int64{0: 0}
   waitGroup := sync.WaitGroup{}
   mutex := sync.Mutex{}

   for i := 0; i < 1000; i++ {
      waitGroup.Add(1)
      go func(i int) {
         mutex.Lock() // 加锁

         m[0]++
         waitGroup.Done()

         mutex.Unlock() // 解锁
      }(i)
   }

   waitGroup.Wait() // 等待所有协程执行完毕

   fmt.Println(m) // map[0:1000]
}

// ========== 总结 ========== //
// 1、在协程里对map进行写操作务必要加锁,防止出现并发写导致程序出错。

Copyright © 2024 码农人生. All Rights Reserved