“golang sync.Map” func main() { m := sync.Map{} m.Store(1,1) go do(m) go do(m) time.Sleep(1*time.Second) fmt.Println(m.Load(1)) } func do (m sync.Map) { i := 0 for i < 10000 { m.Store(1,1) i++ } } 清空 sync.Map https://stackoverflow.com/questions/49355345/how-to-clean-a-sync-map
//erase map: A zero sync.Map is empty and ready for use. map2 = sync.Map{} 在Go 1.6 之前, 内置的 map 类型是部分 goroutine 安全的, 并发的读没有问题, 并发的写可能有问题。自 go 1.6之后, 并发地读写 map 会报错, 这在一些知名的开源库中都存在这个问题, 所以go 1.9之前的解决方案是额外绑定一个锁, 封装成一个新的struct或者单独使用锁都可以。
本文带你深入到sync.Map的具体实现中,看看为了增加一个功能,代码是如何变的复杂的,以及作者在实现sync.Map的一些思想。
有并发问题的map 官方的faq 已经提到内建的map不是线程(goroutine)安全的。
首先,让我们看一段并发读写的代码,下列程序中一个goroutine 一直读,一个goroutine 一只写同一个键值, 即即使读写的键不相同, 而且map 也没有"扩容"等操作, 代码还是会报错。
| — | — | | 12345678910111213141516171819 | package mainfunc main() { m := make(map[int]int) go func() { for { _ = m[1] } }() go func() { for { m[2] = 2 } }() select {}} |
...