map不是goroutine safe的,在多goroutine併發時需要上鎖。
不上鎖會出現什麼問題呢?
資源競爭:會出現髒讀,丟失更新等一系列狀況。如讀到的是舊數據或是讀出來的對象已經被刪除了,引發panic。
鎖用的不對會發生什麼呢?
第一種情況:死鎖(dead lock),卡住。使用時lock了,但沒有unlock,就鎖死了。另外,註冊copy對象裡帶鎖時,注意是不是帶鎖狀態一起拷貝了,這個也會死鎖。
第二種情況:低效。鎖對象時進行了耗時操作,導致了長時間的等待。代碼要儘量減少鎖持有的時間。
怎樣才是上鎖正確的姿勢呢?
總結如下:(按效率從高到低排序)
- 無鎖:無招勝有招。避免使用鎖是最高效的。在不會引發資源競爭的地方就不要用鎖。或者通過設計,將業務放在同一個goroutine下執行。
- concurrent-map
分段鎖: 其中對key進行分段,一個段內使用一個鎖,這樣操作不同的key時,避免鎖的阻塞開銷,提高了效率。但是增加了內存消耗。 - sync.Map
官方實現,內部使用了讀寫兩張表。在讀出寫少效率比較高,但寫多時推薦使用分段鎖。 - 給map加讀寫鎖
在輕量級,使用不是很頻繁時使用。
沒有一種鎖適合所有場合下使用,實際的使用按需求的不同。
閱讀更多 丁玲隆咚嗆 的文章