前言
前一段项目启动一段后爆了个map崩溃的异常
原因是多协程操作了一个map 太过频繁
有几率会导致map崩溃
一开始的解决方法是加读写锁
后来发现效果不是太好
于是使用了sync.map
var m sync.Map //线程安全map
//数据存入
m.Store("index1",1000.00)
//数据取出
t ,bool := m.Load("index1")
if bool{
fmt.Println(t)
}
//类型转换
tmp,bool := t.(float64)
if bool{
fmt.Println(tmp)
}
//删除
m.Delete("index1")
源码
// Store sets the value for a key.
func (m *Map) Store(key, value interface{}) {
read, _ := m.read.Load().(readOnly)
if e, ok := read.m[key]; ok && e.tryStore(&value) {
return
}
m.mu.Lock()
read, _ = m.read.Load().(readOnly)
if e, ok := read.m[key]; ok {
if e.unexpungeLocked() {
// The entry was previously expunged, which implies that there is a
// non-nil dirty map and this entry is not in it.
m.dirty[key] = e
}
e.storeLocked(&value)
} else if e, ok := m.dirty[key]; ok {
e.storeLocked(&value)
} else {
if !read.amended {
// We're adding the first new key to the dirty map.
// Make sure it is allocated and mark the read-only map as incomplete.
m.dirtyLocked()
m.read.Store(readOnly{m: read.m, amended: true})
}
m.dirty[key] = newEntry(value)
}
m.mu.Unlock()
}
可以看出来 Store方法使用了线程锁
use of a Map may significantly reduce lock
contention compared to a Go map paired with a separate Mutex or RWMutex.
看源码时 看到了这句话
对常规map使用锁的话,使用sync.map可以显着减少锁争用
那使用起来应该会比自己手动加锁好一些