众所周知,golang的map是非协程安全的(go1.6版本以后,go1.6之前读安全),而并发读写map的需求应该是很普遍的。举例如下:
package main
import "fmt"
func main() {
a := make(map[int]bool, 0)
for i:=0;i<100;i++{
go func() {
for i := 0; i < 20000; i++ {
a[i] = false
fmt.Printf("%v %v\n",i,a[i])
}
}()
}
}
运行报错:
fatal error: concurrent map writes
1.9版本之前,官方提供的解决方案是自己封装个带同步锁的struct。例如:
package main
import (
"fmt"
"sync"
)
type SafeMap struct{
sync.RWMutex
data map[int]int
}
func main() {
a := SafeMap{data: make(map[int]int)}
for i:=0;i<100;i++{
go func() {
for j := 0; j < 20000; j++ {
a.Lock()
a.data[j] = i
fmt.Printf("%v %v\n", i, j)
a.Unlock()
}
}()
}
}
1.9版本以后,sync包引入了sync.Map,性能比起之前的解决方案有比较大的提升:
package main
import (
"fmt"
"sync"
)
func main() {
a := new(sync.Map)
wg := new(sync.WaitGroup)
wg.Add(100)
for i:=0;i<100;i++{
go func() {
for j := 0; j < 100; j++ {
a.Store(i, j)
}
wg.Done()
}()
}
wg.Wait()
a.Range(func(key, value interface{}) bool {
fmt.Printf("%v %v\n", key, value)
return true
})
}
有疑问加站长微信联系(非本文作者)