golang中使用sync.Map的方法
阿新 • • 發佈:2020-06-16
背景
go中map資料結構不是執行緒安全的,即多個goroutine同時操作一個map,則會報錯,因此go1.9之後誕生了sync.Map
sync.Map思路來自java的ConcurrentHashMap
介面
sync.map就是1.9版本帶的執行緒安全map,主要有如下幾種方法:
Load(key interface{}) (value interface{},ok bool) //通過提供一個鍵key,查詢對應的值value,如果不存在,則返回nil。ok的結果表示是否在map中找到值 Store(key,value interface{}) //這個相當於是寫map(更新或新增),第一個引數是key,第二個引數是value LoadOrStore(key,value interface{}) (actual interface{},loaded bool) //通過提供一個鍵key,查詢對應的值value,如果存在返回鍵的現有值,否則儲存並返回給定的值,如果是讀取則返回true,如果是儲存返回false Delete(key interface{}) //通過提供一個鍵key,刪除鍵對應的值 Range(f func(key,value interface{}) bool) //迴圈讀取map中的值。 //因為for ... range map是內建的語言特性,所以沒有辦法使用for range遍歷sync.Map,但是可以使用它的Range方法,通過回撥的方式遍
實踐
package main import ( "fmt" "sync" ) var num = 0 var addTest *AddTest func init() { addTest = &AddTest{} } type AddTest struct { m sync.Mutex } func (at *AddTest) increment(wg *sync.WaitGroup) { //互斥鎖 at.m.Lock() //當有執行緒進去進行加鎖 num++ at.m.Unlock() //出來後解鎖,其他執行緒才可以進去 wg.Done() } func (at *AddTest) decrement(wg *sync.WaitGroup) { //互斥鎖 at.m.Lock() //當有執行緒進去進行加鎖 num-- at.m.Unlock() //出來後解鎖,其他執行緒才可以進去 wg.Done() } var w sync.WaitGroup var aa map[int]int func main() { var bb sync.Map var wg sync.WaitGroup //aa = make(map[int]int) wg.Add(2) go func() { //wg.Add(1) for i:=0 ;i <100; i++{ //aa[i] = i+1 //fmt.Println("a") bb.Store(i,i+1) } wg.Done() }() go func() { for i:=0 ;i <100; i++{ //aa[i] = i+1 //fmt.Println("a") bb.Store(i,i+1) } wg.Done() }() wg.Wait() bb.Range(func(k,v interface{}) bool { fmt.Println("iterate:",k,v) return true } }
總結
- 讀寫鎖和互斥鎖 讀寫鎖: 可以獲取多個讀鎖,只有讀寫衝突(加了讀鎖的時候,其它執行緒不能寫) 互斥鎖:跟讀寫操作無關,加了鎖,鎖內的資源就執行緒獨享
- 個人感覺使用起來不太方便,不如根據實際場景自己互斥鎖。比如map都是可讀的,只有寫的時候需要序列執行,則寫操作封裝互斥鎖即可
- sync.Map因為內部的操作較多等原因,並不適合大量寫的場景(適合大量讀,少量寫)。
- sync.Map的原理詳見:https://www.jb51.net/article/188788.htm
參考
https://www.kancloud.cn/liupengjie/go/718991
https://colobu.com/2017/07/11/dive-into-sync-Map/
到此這篇關於golang中使用sync.Map的文章就介紹到這了,更多相關golang中使用sync.Map內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!