Golang map執行緒安全實現及sync.map使用及原理解析。
前言
眾所周知,Golang 的map是不安全的,所以sync包提供了執行緒安全的map。接下來就是把我對sync.map的理解寫出來分享給各位。
一、為什麼map執行緒不安全?
map不是執行緒安全的。在同一時間段內,讓不同 goroutine 中的程式碼,對同一個字典進行讀寫操作是不安全的。字典值本身可能會因這些操作而產生混亂,相關的程式也可能會因此發生不可預知的問題。
二、配合(鎖)實現執行緒安全的map。
1.悲觀鎖的形式
悲觀鎖:進來的每一步操作都認為同時會有其他程式影響操作,所以提前加鎖。
lock.Lock()
//map的增刪改查操作
lock.UnLock()
2.樂觀鎖的形式
樂觀鎖:因為map執行緒不安全是同時:讀&&寫||寫&&寫 造成的,所以在map寫的時候加上鎖就會提高map的效能。
//查
lock.Lock()
//map的增刪改操作
lock.UnLock()
3.根據map實現原理,對小範圍進行加鎖。
另一種設想是在buckets層面加鎖,根據樂觀鎖的情況進行小範圍加鎖。
三、sync.map實現的原理。
1、sync.Map 的實現原理可概括為:
過 read 和 dirty 兩個欄位將讀寫分離,讀的資料存在只讀欄位 read 上,將最新寫入的資料則存在 dirty 欄位上
讀取時會先查詢 read,不存在再查詢 dirty,寫入時則只寫入 dirty
讀取 read 並不需要加鎖,而讀或寫 dirty 都需要加鎖
另外有 misses 欄位來統計 read 被穿透的次數(被穿透指需要讀 dirty 的情況),超過一定次數則將 dirty 資料同步到 read 上
對於刪除資料則直接通過標記來延遲刪除
2、sync.Map 使用方法:
var ma sync.Map// 該型別是開箱即用,只需要宣告既可
ma.Store("key", "value") // 儲存值
ma.Delete("key") //刪除值
ma.LoadOrStore("key", "value")// 獲取值,如果沒有則儲存
fmt.Println(ma.Load("key"))//獲取值
//遍歷
ma.Range(func(key, value interface{}) bool {
fmt.Printf("key:%s ,value:%s \n", key, value)
//如果返回:false,則退出迴圈,
return true
})
總結
map底層雖然寫的尤為漂亮,但是為了效率,沒有吧執行緒安全安排上,所以另外加了sync.map,相容執行緒安全。在我的理解中,sync.map實現就是依靠兩張map對讀操作和寫操作分離,後續根據需要在把dirty map合入 read map中。相對於樂觀鎖實現的方式,寫程式執行的時候,讀程式也可能在read map上進行。
如有問題請聯絡本人指正,謝謝~
相關文章
- JAVA執行緒池的原理及使用Java執行緒
- Map實現執行緒安全的3種方式執行緒
- [Golang併發]Sync.mapGolang
- Java執行緒池原理及分析Java執行緒
- 深入理解golang:sync.mapGolang
- 小度分享-【多執行緒工作及執行緒安全】執行緒
- 面試必問-幾種執行緒安全的Map解析面試執行緒
- Java多執行緒-基礎及實現Java執行緒
- Java執行緒池原始碼及原理Java執行緒原始碼
- 虛擬執行緒原理及效能分析執行緒
- SpringMVC實現原理及解析SpringMVC
- 多執行緒原理實現執行緒
- Swift實現多執行緒map函式Swift執行緒函式
- 如何設計並實現一個執行緒安全的 Map ?(下篇)執行緒
- 如何設計並實現一個執行緒安全的 Map ?(上篇)執行緒
- 深入理解 Java 多執行緒、Lambda 表示式及執行緒安全最佳實踐Java執行緒
- Goland sync.Map大白話解析GoLand
- 執行緒同步及執行緒鎖執行緒
- JavaScript 預解析的原理及實現JavaScript
- KVO使用及實現原理
- 執行緒池的實現原理執行緒
- 執行緒屏障CyclicBarrier實現原理執行緒
- 執行緒池的介紹及簡單實現執行緒
- 執行緒的建立及執行緒池執行緒
- 深入原始碼,深度解析Java 執行緒池的實現原理原始碼Java執行緒
- Android執行緒篇(一)實現執行緒的幾種方法及區別Android執行緒
- 執行緒安全佇列(使用互斥鎖進行實現)執行緒佇列
- InnoDB MVCC實現原理及原始碼解析MVC原始碼
- 【GoLang 那點事】深入 Go 的 Map 使用和實現原理Golang
- 踩了 Golang sync.Map 的一個坑Golang
- 執行緒池ThreadPoolExecutor實現原理執行緒thread
- 多執行緒-多執行緒方式2的思路及程式碼實現執行緒
- JUC(4)---java執行緒池原理及原始碼分析Java執行緒原始碼
- 玩轉java多執行緒 之多執行緒基礎 執行緒狀態 及執行緒停止實戰Java執行緒
- JVM執行原理及Stack和Heap的實現過程JVM
- Golang Sync.WaitGroup 使用及原理GolangAI
- 多執行緒的安全問題及解決方案執行緒
- Python執行緒安全問題及解決方法Python執行緒