golang 自带的map不是并发安全的,并发读写会报错:
fatal error: concurrent map read and map write
一般的解决方式是加锁,控制互斥。
1.加锁的map
如下代码所示:
package main
import (
"fmt"
"sync"
"time"
)
type Map struct {
m map[int]int
sync.RWMutex
}
func(this *Map) Get(key int) int {
this.RLock()
defer this.RUnlock()
v := this.m[i]
return v
}
func(this *Map) Set(k, v int) {
this.Lock()
defer this.Unlock()
this.m[k] = v
}
func main(){
newMap := &Map{m: make(map[int]int)}
for i := 0; i< 10000; i<++ {
go newMap.Set(i, i)
}
for i := 0; i< 10000; i<++ {
go fmt.Println(i, newMap.Get(i))
}
time.Sleep(time.Second)
}
2.使用sync.Map
从1.9版本开始,sync
包中提供了并发安全的map,也就是sync.Map
,其内部实现上已经做了互斥处理。
使用举例如下:
例子中,使用Store
设置kv,使用Load
读取kv,使用Delete
删除kv。
package main
import (
"fmt"
"sync"
)
type Counter struct {
count int
}
func main() {
var m sync.Map
m.Store("a", 1)
m.Store("b", 2)
counter := &Counter{count:2}
m.Store("c", counter)
fmt.Println("m:", m)
v, ok := m.Load("a")
fmt.Println("a v:", v, ", ok:", ok)
fmt.Printf("a type: %T\n", v)
v, ok = m.Load("b")
fmt.Println("b v:", v, ", ok:", ok)
v, ok = m.Load("c")
fmt.Println("c v:", v, ", ok:", ok)
fmt.Printf("c type %T\n", v)
vc,_ := v.(*Counter)
vc.count += 1
fmt.Println("================")
v, ok = m.Load("c")
fmt.Println("c v:", v, ", ok:", ok)
m.Delete("d")
}
output:
m: {{0 0} {{map[] true}} map[a:0xc00000e028 b:0xc00000e030 c:0xc00000e038] 0}
a v: 1 , ok: true
a type: int
b v: 2 , ok: true
c v: &{2} , ok: true
c type *main.Counter
================
c v: &{3} , ok: true
3.参考
Just try, don't shy.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
2020-02-27 slave_net_timeout, MASTER_HEARTBEAT_PERIOD, MASTER_CONNECT_RETRY,以及 MASTER_RETRY_COUNT设置和查看