1. sync.Map
1.1. map并發不安全
go1.6以后map有了并發的安全檢查,所以如果在并發環境中讀寫map就會報錯
func unsafeMap() { // 創建一個map物件 m := make(map[int]int) go func() { for { // 嘗試讀取資料 _ = m[1] } }() go func() { for { // 嘗試寫入資料 m[2] = 2 } }() // 阻塞 select {}}// output// fatalerror: concurrent map read and map write1.2 安全map
并發環境下面使用安全的map
1.2.1 自定義結構體
// 通過內嵌讀寫鎖的方式,保證我們使用map的安全性type MyMap struct{ sync.RWMutex m map[string]int // 需要一個并發的map[string]int型別}// 封裝一個創建map物件的方法func NewMyMap()*MyMap{ smp:=new(MyMap) smp.m = make(map[string]int) return smp}注意:我們定義使用什么型別的map,那么就內置什么型別的map
1.2.2 sync.Map
go1.9以后sync包中加入了安全的map物件,,syn.Map不支持普通的map操作,需要使用sync.Map提供的api使用
創建sync.Map物件
//1. 不需要通過map的方式進行創建,通過宣告的方式或者new創建即可var smap sync.Map//2. 通過new的方式創建smap:=new(sync.Map)sync.Map 存盤資料store方法
//func (m *Map) Store(key, value interface{})// key,value 都是介面型別,可以存盤任何型別的資料smap.Store(1,"MrSun")sync.Map讀取資料
// func (m *Map) Load(key interface{}) (value interface{}, ok bool)// key: 鍵,value: 如果資料存在則回傳對應的值,不存在則回傳nil,ok: 表示值知否被找到// 記得對資料斷言處理val,ok:=smap.Load(1)sync.Map,存在則讀取,不存在存盤
// func (m *Map) LoadOrStore(key, value interface{}) (actual interface{}, loaded bool)// key,value: 要存盤的key與value//actual: 如果存在則回傳存在的值,如果不存在則存盤并回傳存盤的值// laoded: 如果資料存在,則true,如果資料不存在則falseactual, loaded := smap.LoadOrStore(1, "MrSun")sync.Map 遍歷
// 創建mapsmap:=new(sync.Map)smap.LoadOrStore(1, "MrSun")smap.LoadOrStore(2, "hello")smap.LoadOrStore(3, "golang")smap.LoadOrStore(4, "bilili")//func (m *Map) Range(f func(key, value interface{}) bool)// 用戶處理資料的回呼函式,回呼函式的引數是key,value,回傳值是boolsmap.Range(func(key, value interface{}) bool { smap.Store(5,"heihei") fmt.Println(key,value) return true})
// 注意:Range方法遍歷的是map的副本 sync.Map 資料洗掉// func (m *Map) Delete(key interface{})// key: 要洗掉資料的key值smap.Delete(1)
1.2.3 sync.Map與內置讀寫鎖性能對比

4核心以前內置的讀寫鎖map性能要高
4核心后,sync.Map 性能要高
sync.Map 性能穩定
1.2.4 sync.Map使用場景
The Map type is optimized for two common use cases:
when the entry for a given key is only ever written once but read many times, as in caches that only grow.
when multiple goroutines read, write, and overwrite entries for disjoint sets of keys. In these two cases, use of a Map may significantly reduce lock contention compared to a Go map paired with a separate Mutex or RWMutex.
寫少讀多的情況
多goroutine,讀、寫、復寫 不同資料的情況 【沒遇到過】
多核心情況使用
建議:沒有特別要求的情況,兩者都可以,go1.9以后建議直接使用sync.Map
1.2.5 sync.Map原始碼剖析
sync.Map
2. Concurrent Map
并發安全map,類似java下面的java.util.ConcurrentHashMap,適合讀寫都相對比較頻繁的情況
2.1 基本原理
采用分段鎖機制,從而提高并發安全的性能

2.2 concurrent map下載

# github 星標 最高的一個go get "github.com/orcaman/concurrent-map"
2.2 基本使用
不同的第三方包模塊使用API都不一樣,使用那個模塊需要查看對應模塊的檔案
import "github.com/orcaman/concurrent-map"func concurrentMap() { mp:=cmap.New() // 存盤值,key只能是string型別,value可以是任意型別 mp.Set("1","hello") mp.Set("2","golang") //val: 如果存在則回傳值,不存在則回傳nil // ok: 表示值如果存在則是true,如果不存在則是false val,ok:=mp.Get("2") if ok{ fmt.Println(val.(string)) } mp.Remove("1") _,ok=mp.Get("1") if !ok{ fmt.Println("data is not exist") }}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/59802.html
標籤:Go
上一篇:GO匯總
下一篇:多任務的使用模式
