使用sync.Map实现安全并发读写
Go语言的sync包中新增加了一个类型叫做sync.Map,它专门用于并发读写map。与普通的map相比,sync.Map具有以下特点: 1. 在并发读写的情况下,不需要额外的锁来保护数据的一致性。这意味着多个goroutine可以同时对map进行读写,而不会导致数据竞争。 2. sync.Map内部使用了一种高效的算法,能够快速定位到需要读写的元素,从而提升了性能。下面是一个使用sync.Map的例子:
``` // 创建一个sync.Map var m = sync.Map{} // 添加键值对 m.Store("key", "value") // 获取键对应的值 value, ok := m.Load("key") // 删除键值对 m.Delete("key") ``` 在上面的例子中,我们首先创建了一个sync.Map对象m,然后使用Store方法添加了一个键值对。接着,我们可以使用Load方法获取这个键对应的值,并通过第二个返回值判断是否找到了对应的值。最后,我们可以使用Delete方法删除指定的键值对。sync.Map的同步特性
sync.Map除了支持并发读写,还提供了一些其他有用的同步特性,让我们更加方便地操作map。下面是一些常用的同步特性: 1. LoadOrStore:当map中不存在指定的键时,可以使用LoadOrStore方法添加新的键值对。 2. Range:可以遍历map中的所有键值对。需要注意的是,遍历期间不会受到其他goroutine的影响。 3. LoadAndDelete:可以同时获取指定键对应的值,并将该键值对从map中删除。下面是一个使用sync.Map的示例代码:
``` // 创建一个sync.Map var m = sync.Map{} func main() { // 启动多个goroutine并发访问map for i := 0; i < 100; i++ { go func(i) { // 加锁 value, ok := m.LoadOrStore(i, i) if ok { fmt.Println("Value", value, "found for key", i) } else { fmt.Println("No value found for key", i) } // 解锁 m.Delete(i) }(i) } // 防止主goroutine提前退出 time.Sleep(time.Second) } ``` 在上面的例子中,我们创建了一个sync.Map对象m,并通过多个goroutine并发地访问这个map。每个goroutine都会使用LoadOrStore方法向map中添加键值对,并尝试打印出特定的值。然后,我们又使用Delete方法删除了这个键值对。