歡迎您光臨本站 註冊首頁

golang中使用sync.Map的方法

←手機掃碼閱讀     retouched @ 2020-06-17 , reply:0

背景

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.kancloud.cn/liupengjie/go/718991

https://colobu.com/2017/07/11/dive-into-sync-Map/

                

   


[retouched ] golang中使用sync.Map的方法已經有245次圍觀

http://coctec.com/docs/program/show-post-238870.html