mapfatalmapaccess1mapkeymapfatal
ifh.flags&hashWriting!=0{
fatal("concurrentmapreadandmapwrite")
}
varm=make(map[int]int)
//往map写key的协程
gofunc(){
//往map写入数据
fori:=0;i0;i--{
_=m[i]
}
}()
//等待两个协程执行完毕
time.Sleep(time.Second)
fatalerror:concurrentmapreadandmapwrite
mapmapmapmapsync.Mutexsync.Mutex
varm=make(map[int]int)
//互斥锁
varmusync.Mutex
//写map的协程
gofunc(){
fori:=0;i0;i--{
mu.Lock()//读map,加互斥锁
_=m[i]
mu.Unlock()
}
}()
time.Sleep(time.Second)
sync.Mutexsync.Mutexsync.Mutexsync.Mutexsyncsync.RWMutexsync.RWMutex
varm=make(map[int]int)
//读写锁(允许并发读,写的时候是互斥的)
varmusync.RWMutex
//写入map的协程
gofunc(){
fori:=0;i0;i--{
//读取的时候需要加锁,但是这个锁是读锁
//多个协程可以同时使用RLock而不需要等待
mu.RLock()
_=m[i]
mu.RUnlock()
}
}()
//另外一个读取map的协程
gofunc(){
fori:=20000;i>10000;i--{
//读取的时候需要加锁,但是这个锁是读锁
//多个协程可以同时使用RLock而不需要等待
mu.RLock()
_=m[i]
mu.RUnlock()
}
}()
time.Sleep(time.Second)
RLockLockUnlocksync.RWMutexsync.Mutexsync.RWMutexKeyssync.Mutexsync.RWMutexsync.Mutexsync.RWMutexsync.Mapsync.Mapsync.RWMutex
varaint32
varwgsync.WaitGroup
wg.Add(2)
gofunc(){
fori:=0;i
a2000020000
varaatomic.Int32
varwgsync.WaitGroup
wg.Add(2)
gofunc(){
fori:=0;i
funcBenchmarkMutexAdd(b*testing.B){
varaint32
varmusync.Mutex
fori:=0;i
BenchmarkMutexAdd-1210000000010.07ns/op
BenchmarkAtomicAdd-122051969685.847ns/op
funcBenchmarkMutex(b*testing.B){
varmusync.RWMutex
fori:=0;i
BenchmarkMutex-1210000000010.12ns/op
BenchmarkAtomic-1210000000000.3133ns/op
BenchmarkMutexsync.Mapsync.RWMutexsync.MapLoadsync.Mapkeyreadkeysync.Mapkeysync.MapLoad
//Load方法从sync.Map里面读取数据。
func(m*Map)Load(keyany)(valueany,okbool){
//先从只读map里面读取数据。
//这一步是不需要锁的,只有一个原子操作。
read:=m.loadReadOnly()
e,ok:=read.m[key]
if!ok&&read.amended{//如果没有找到,并且dirty里面有一些read中没有的key,那么就需要从dirty里面读取数据。
//这里才需要锁
m.mu.Lock()
read=m.loadReadOnly()
e,ok=read.m[key]
if!ok&&read.amended{
e,ok=m.dirty[key]
m.missLocked()
}
m.mu.Unlock()
}
//key不存在
if!ok{
returnnil,false
}
//使用原子操作读取
returne.Load()
}
sync.Mapsync.Mapsync.Mapsync.Mapmapsync.Mapsync.Mapsync.MapCRUDStoreStoreLoadRangeDelete
varmsync.Map
//写入/修改
m.Store("foo",1)
//读取
fmt.Println(m.Load("foo"))//1true
//遍历
m.Range(func(key,valueinterface{})bool{
fmt.Println(key,value)//foo1
returntrue
})
//删除
m.Delete("foo")
fmt.Println(m.Load("foo"))//nilfalse
sync.Mapkeyvalueinterface{}keyvaluemapkeyvaluemap[any]anyRangefalsesync.Mapsync.Map
TheMaptypeisoptimizedfortwocommonusecases:(1)whentheentryforagiven
keyisonlyeverwrittenoncebutreadmanytimes,asincachesthatonlygrow,
or(2)whenmultiplegoroutinesread,write,andoverwriteentriesfordisjoint
setsofkeys.Inthesetwocases,useofaMapmaysignificantlyreducelock
contentioncomparedtoaGomappairedwithaseparateMutexorRWMutex.
keymapMutexRWMutexsync.Map