8.27Go之容器之syncMap

8.27Go之容器之syncMap

Map的特点

map 在并发情况下,只读是线程安全的,同时读写是线程不安全的

并发的 map 读和 map 写,使用了两个并发函数不断地对 map 进行读和写而发生了竞态问题,map 内部会对这种并发操作进行检查并提前发现。

示例:

package main

func main() {
/*声明一个Map*/
mapInt := make(map [int] int)

/*开启一段并发代码,不断地写入value*/
go func() {
for {
mapInt[1] = 1
}
}()

/*开启另一段并发代码,读取mapInt*/
go func() {
for {
_ =mapInt[1]
}
}()

/*输出*/
for {

}
}

syncMap

特点:

  • syncMap是一个包,包下面有安全操作Map的方法

  • 无须初始化,直接声明即可。

  • sync.Map 不能使用 map 的方式进行取值和设置等操作,而是使用 sync.Map 的方法进行调用,Store 表示存储,Load 表示获取,Delete 表示删除。

  • 使用 Range 配合一个回调函数进行遍历操作,通过回调函数返回内部遍历出来的值,Range 参数中回调函数的返回值在需要继续迭代遍历时,返回 true,终止迭代遍历时,返回 false。

package main

import (
"fmt"
"sync"
)

func main() {
var scene sync.Map

/*调用包内的方法将键值对保存进去*/
scene.Store("name", "JunkingBoy")
scene.Store("age", 22)
scene.Store("long", 18)
   /*
键值对保存到 sync.Map 中,sync.Map 将键和值以 interface{} 类型进行保存。
所以可以是任意类型的value
*/

/*使用包内方法从键中取值*/
fmt.Println(scene.Load("long"))

/*删除对应的键值对*/
scene.Delete("age")

//遍历键值对--->调用sync包下的方法
scene.Range(func(key, value interface{}) bool {
fmt.Println("iterate", key, value)
return true
})
}

syncMap的缺点:

  • sync.Map 没有提供获取 map 数量的方法,替代方法是在获取 sync.Map 时遍历自行计算数量,sync.Map 为了保证并发安全有一些性能损失,因此在非并发情况下,使用 map 相比使用 sync.Map 会有更好的性能。

  •  

It's a lonely road!!!
原文地址:https://www.cnblogs.com/JunkingBoy/p/15195057.html