所以在并发的情况下不能直接使用map:var m = make(map[string]interface{}):time.Sleep(2 * time.Second);= "WangWu" + strconv.Itoa(i):writeMap(m;writeMap(m:func writeMap(m map[string]int;};运行时;原理
golang中的map不是线程安全的,所以在并发的情况下不能直接使用map。
反面例子package main import ( "strconv" "time" ) var m = make(map[string]interface{}) func main() { testMap(m) time.Sleep(2 * time.Second) } func testMap() { go func() { for i := 0; i < 10; i++ { name := "WangWu" + strconv.Itoa(i) writeMap(m, name, i) } }() go func() { for i := 0; i < 10; i++ { name := "ZhuoQi" + strconv.Itoa(i) writeMap(m, name, i) } }() } func writeMap(m map[string]int, key string, val int) { m[key] = val }
运行时,会报错:
Fatal error: concurrent map writes解决办法
package main import ( "fmt" "strconv" "sync" "time" ) // 定义锁 var locker = &sync.RWMutex{} var m = make(map[string]interface{}) func main() { testMap() time.Sleep(2 * time.Second) fmt.Println(m) } func testMap() { go func() { for i := 0; i < 10; i++ { name := "WangWu" + strconv.Itoa(i) writeMap(name, i) } }() go func() { for i := 0; i < 10; i++ { name := "ZhuoQi" + strconv.Itoa(i) writeMap(name, i) } }() } func writeMap(key string, val int) { locker.Lock() m[key] = val locker.Unlock() }2. 使用sync.Map
package main import ( "fmt" "strconv" "sync" "time" ) var m = sync.Map{} func main() { testMap() time.Sleep(2 * time.Second) m.Range(func(k, v interface{}) bool { fmt.Println("map:", k, v) return true }) } func testMap() { go func() { for i := 0; i < 10; i++ { name := "WangWu" + strconv.Itoa(i) m.Store(name, i) } }() go func() { for i := 0; i < 10; i++ { name := "ZhuoQi" + strconv.Itoa(i) m.Store(name, i) } }() }
原文地址:https://cloud.tencent.com/developer/article/2029134
评论列表