前言
在 Golang 中 map 不是并发安全的,自 1.9 才引入了 sync.Map ,sync.Map 的引入确实解决了 map 的并发安全问题,不过 sync.Map 却没有实现 len() 函数,如果想要计算 sync.Map 的长度,稍微有点麻烦,需要使用 Range 函数。
map 并发操作出现问题
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| func main() { demo := make(map[int]int)
go func() { for j := 0; j < 1000; j++ { demo[j] = j } }()
go func() { for j := 0; j < 1000; j++ { fmt.Println(demo[j]) } }()
time.Sleep(time.Second * 1) }
|
执行输出:
1
| fatal error: concurrent map read and map write
|
sync.Map 解决并发操作问题
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| func main() { demo := sync.Map{}
go func() { for j := 0; j < 1000; j++ { demo.Store(j, j) } }()
go func() { for j := 0; j < 1000; j++ { fmt.Println(demo.Load(j)) } }()
time.Sleep(time.Second * 1) }
|
执行输出:
1 2 3 4 5 6
| <nil> false 1 true
...
999 true
|
计算 map 长度
1 2 3 4 5 6 7 8 9
| func main() { demo := make(map[int]int)
for j := 0; j < 1000; j++ { demo[j] = j }
fmt.Println("len of demo:", len(demo)) }
|
执行输出:
计算 sync.Map 长度
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| func main() { demo := sync.Map{} for j := 0; j < 1000; j++ { demo.Store(j, j) }
lens := 0 demo.Range(func(key, value interface{}) bool { lens++ return true })
fmt.Println("len of demo:", lens) }
|
执行输出:
小结
Load 加载 key 数据
Store 更新或新增 key 数据
Delete 删除 key 数据
Range 遍历数据
LoadOrStore 如果存在 key 数据则返回,反之则设置
LoadAndDelete 如果存在 key 数据则删除
以上,希望对你能够有所帮助。