在Go 1.6之前,安全内置的安全map类型是部分goroutine安全的,并发的安全读没有问题,并发的安全写可能有问题。自go 1.6之后,安全并发地读写map会报错,安全这在一些知名的安全开源库中都存在这个问题,所以go 1.9之前的安全解决方案是额外绑定一个锁,封装成一个新的安全struct或者单独使用锁都可以。
在Go1.9之前,安全go自带的安全map不是并发安全的,也就是安全说,我们需要自己再封装一层,安全给map加上把读写锁,安全比如像下面这样:

用MapWithLock的安全读写锁去控制map的高防服务器并发安全。
但是到了Go1.9发布,它有了一个新的特性,那就是sync.map,它是原生支持并发安全的map,不过它的用法和以前我们熟悉的map完全不一样,主要还是因为sync.map封装了更为复杂的数据结构,以实现比之前加锁map更优秀的性能。
sync.map就是1.9版本带的线程安全map,主要有如下几种方法:
func (m Map) Load(key interface{}) (value interface{}, ok bool)通过提供一个键key,查找对应的值value,如果不存在,则返回nil。ok的结果表示是b2b信息网否在map中找到值
func (m Map) Store(key, value interface{})这个相当于是写map(更新或新增),第一个参数是key,第二个参数是value
func (m Map) LoadOrStore(key, value interface{}) (actual interface{}, loaded bool)通过提供一个键key,查找对应的值value,如果存在返回键的现有值,否则存储并返回给定的值,如果是读取则返回true,如果是存储返回false
func (m Map) Delete(key interface{})通过提供一个键key,删除键对应的值
func (m Map) Range(f func(key, value interface{}) bool)循环读取map中的值。
因为for … range map是内置的语言特性,所以没有办法使用for range遍历sync.Map, 但是可以使用它的Range方法,通过回调的方式遍历。
sync.Map应用
package main import ( "fmt" "sync" ) type userInfo struct { Name string Age int } // 声明 sync.Map var m sync.Map func main() { // 写入 m.Store(1, "one") m.Store("oldboy", "Go") // 查找 val, ok := m.Load(1) fmt.Println("Load : ", val, ok) // one true // 查找 or 写入 val, ok = m.LoadOrStore("oldboy", "Golang") fmt.Println("LoadOrStore : ", val, ok) // Go true val, ok = m.LoadOrStore("2", "two") fmt.Println("LoadOrStore : ", val, ok) // two false // range m.Range(func(k, v interface{}) bool { fmt.Println(k, v) return true }) // 删除 m.Delete(1) m.Delete(2) m.Range(func(k, v interface{}) bool { fmt.Println(k, v) return true }) }香港云服务器







