map 和 sync.Map
在go中,map是非线程安全的,就是说当多个协程来操作同一个map时,可能发生报错,下面是一个示例
package main
import (
"fmt"
"strconv"
"sync"
)
func main() {
var m1 = make(map[string]int)
fmt.Println("vim-go")
wg := sync.WaitGroup{}
for i := 0; i < 50; i++ {
go func(i int) {
wg.Add(1)
m1[strconv.Itoa(i)] = i
fmt.Printf("key:%s,value:%d\n", strconv.Itoa(i), m1[strconv.Itoa(i)])
wg.Done()
}(i)
}
wg.Wait()
}
运行以上代码,可以得到如下错误:
fatal error: concurrent map writes
fatal error: concurrent map writes
意思大概是说并发写,但是在实际工作中,难免需要多个协程来操作同一个map,为了解决这个问题,go提供了一个开箱即用的并发安全的map,叫sync.Map,他的使用方法如下:
package main
import (
"fmt"
"strconv"
"sync"
)
func main() {
var m1 = sync.Map{}
fmt.Println("vim-go")
wg := sync.WaitGroup{}
for i := 0; i < 50; i++ {
go func(i int) {
wg.Add(1)
m1.Store(strconv.Itoa(i) , i)
load, ok := m1.Load(strconv.Itoa(i))
fmt.Printf("key:%s,value:%v,%v\n", strconv.Itoa(i),load,ok )
wg.Done()
}(i)
}
wg.Wait()
}
运行发现,是没有错误的:
key:4,value:4,true
key:3,value:3,true
key:19,value:19,true
key:20,value:20,true
key:21,value:21,true
key:24,value:24,true
key:18,value:18,true
key:49,value:49,true
key:46,value:46,true
key:1,value:1,true
key:17,value:17,true
key:0,value:0,true
key:48,value:48,true
key:25,value:25,true
key:26,value:26,true
key:13,value:13,true
key:10,value:10,true
key:29,value:29,true
key:9,value:9,true
key:27,value:27,true
key:23,value:23,true
key:11,value:11,true
key:28,value:28,true
key:32,value:32,true
key:14,value:14,true
key:6,value:6,true
key:30,value:30,true
key:37,value:37,true
key:41,value:41,true
key:40,value:40,true
key:36,value:36,true
key:43,value:43,true
key:7,value:7,true
key:5,value:5,true
key:12,value:12,true
key:31,value:31,true
key:2,value:2,true
key:35,value:35,true
key:42,value:42,true
key:16,value:16,true
key:34,value:34,true
key:39,value:39,true
key:8,value:8,true
key:47,value:47,true
key:45,value:45,true
key:44,value:44,true
key:15,value:15,true
key:22,value:22,true
key:38,value:38,true
key:33,value:33,true