go語言:給map上鎖

map不是goroutine safe的,在多goroutine併發時需要上鎖。

不上鎖會出現什麼問題呢?

資源競爭:會出現髒讀,丟失更新等一系列狀況。如讀到的是舊數據或是讀出來的對象已經被刪除了,引發panic。

鎖用的不對會發生什麼呢?

第一種情況:死鎖(dead lock),卡住。使用時lock了,但沒有unlock,就鎖死了。另外,註冊copy對象裡帶鎖時,注意是不是帶鎖狀態一起拷貝了,這個也會死鎖。

第二種情況:低效。鎖對象時進行了耗時操作,導致了長時間的等待。代碼要儘量減少鎖持有的時間。

怎樣才是上鎖正確的姿勢呢?

總結如下:(按效率從高到低排序)

  1. 無鎖:無招勝有招。避免使用鎖是最高效的。在不會引發資源競爭的地方就不要用鎖。或者通過設計,將業務放在同一個goroutine下執行。
  2. concurrent-map
    分段鎖: 其中對key進行分段,一個段內使用一個鎖,這樣操作不同的key時,避免鎖的阻塞開銷,提高了效率。但是增加了內存消耗。
  3. sync.Map

    官方實現,內部使用了讀寫兩張表。在讀出寫少效率比較高,但寫多時推薦使用分段鎖。
  4. 給map加讀寫鎖
    在輕量級,使用不是很頻繁時使用。

沒有一種鎖適合所有場合下使用,實際的使用按需求的不同。


分享到:


相關文章: