在瞭解了加鎖和鎖重入以後,最須要了解的仍是在分佈式場景下或者多線程併發加鎖是如何處理的?多線程
先來看結果,在多線程對 /locks/lock_01
加鎖時,是在後面又建立了新的臨時節點。併發
這塊在加鎖方法 CreateBuilderImpl#pathInForeground
中已經介紹過框架
這裏判斷 /locks/lock_01
路徑已經存在,會直接建立新的臨時順序節點。分佈式
真正判斷鎖是否獲取成功,實際上是在 LockInternals#attemptLock
方法中的 internalLockLoop
方法中。oop
internalLockLoop
方法的主要做用是判斷加鎖結果,以及獲取鎖失敗時,對其餘節點的監聽。ui
/locks/lock_01
下的全部子節點,按照從小到大排序,判斷本身是否是獲取到鎖,沒有獲取到就監聽本身前一個節點;是否獲取鎖的代碼在 StandardLockInternalsDriver#getsTheLock
線程
這塊就是判斷是否爲最小節點,由於在 getSortedChildren
中已經對全部節點排序,因此方法中的 List<String> children
是有序的。code
maxLeases
是在 InterProcessMutex
初始化的時候,指定的值爲 1。blog
最終這裏的結果是,判斷本身是否是最小,不是最小,就將 pathToWatch 設置爲前一個節點。排序
只監聽本身的前一個節點,能夠避免羊羣效應!
爲何要進行等待呢?
由於是爲了防止無效自旋,由於這裏有監聽機制,會監聽上一個節點是否釋放。
這塊是 ZooKeeper 的 Watcher 監聽機制,在節點釋放的時候,會進行回調,而後使用 Java 的 notifyAll 方法通知全部的 wait 線程。而後這裏的 while trye 會繼續執行,從新檢查是否得到鎖等。
本文主要介紹了基於 ZooKeeper 的分佈式鎖框架 Curator 在併發場景下的鎖競爭問題。
重點須要瞭解的是: