Go中自己通过make创建的map不是线程安全的,具体体现在多线程添加值和修改值下会报如下错误:
fatal error : concurrent map writes
这个错类似于java中多线程读写线程不安全的容器时报的错。
Go为了解决这个问题,专门给我们提供了一个并发安全的map,这个并发安全的map不用通过make创建,拿来即可用,并且他提供了一些不同于普通map的操作方法。
参考如下代码示例:
package main
import (
"fmt"
"sync"
)
//创建一个sync包下的线程安全map对象
var myConcurrentMap = sync.Map{}
//遍历数据用的
var myRangeMap = sync.Map{}
func main() {
//存储数据
myConcurrentMap.Store(1,"li_ming")
//取出数据
name,ok := myConcurrentMap.Load(1)
if(!ok) {
fmt.Println("不存在")
return
}
//打印值 li_ming
fmt.Println(name)
//该key有值,则ok为true,返回它原来存在的值,不做任何操作;该key无值,则执行添加操作,ok为false,返回新添加的值
name2, ok2 := myConcurrentMap.LoadOrStore(1,"xiao_hong")
//因为key=1存在,所以打印是 li_ming true
fmt.Println(name2,ok2)
name3, ok3 := myConcurrentMap.LoadOrStore(2,"xiao_hong")
//因为key=2不存在,所以打印是 xiao_hong false
fmt.Println(name3,ok3)
//标记删除值
myConcurrentMap.Delete(1)
//取出数据
//name4,ok4 := myConcurrentMap.Load(1)
//if(!ok4) {
// fmt.Println("name4=不存在")
// return
//}
//fmt.Println(name4)
//遍历数据
rangeFunc()
}
//遍历
func rangeFunc(){
myRangeMap.Store(1,"xiao_ming")
myRangeMap.Store(2,"xiao_li")
myRangeMap.Store(3,"xiao_ke")
myRangeMap.Store(4,"xiao_lei")
myRangeMap.Range(func(k, v interface{}) bool {
fmt.Println("data_key_value = :",k,v)
//return true代表继续遍历下一个,return false代表结束遍历操作
return true
})
}