1. 程式人生 > >普通鎖和分散式鎖

普通鎖和分散式鎖

1、普通鎖和分散式鎖

    為什麼有了普通鎖還需要分散式鎖,當然是因為普通鎖和分散式鎖各有各的使用場景。普通針對多執行緒的場景,一般可以synchronized和lock。而分散式針對的是分散式的環境,系統部署在多個機器中,也會出現併發問題,並且場景是多個程序之間的併發問題。使用記憶體標記無法解決這個問題,因為記憶體是執行緒共享的。

2、普通鎖

 主要有兩種synchronized和lock。下面介紹一下兩個鎖的異同點:

      1)Lock是一個介面,而synchronized是Java中的關鍵字,synchronized是內建的語言實現;

  2)synchronized除了在流程走完釋放鎖,還在發生異常時,會自動釋放執行緒佔有的鎖,因此不會導致死鎖現象發生;而Lock在發生異常時,如果沒有主動通過unLock()去釋放鎖,則很可能造成死鎖現象,因此使用Lock 時需要在finally塊中釋放鎖;

  3)Lock可以讓等待鎖的執行緒響應中斷,而synchronized卻不行,使用synchronized時,等待的執行緒會一直等待下去,不能夠響應中斷;當通過lockInterruptibly()方法獲取某個鎖時,如果不能獲取到,只有進行等待的情況下,是可以響應中斷的。

  4)通過Lock可以知道有沒有成功獲取鎖,而synchronized卻無法辦到。

  5)Lock可以提高多個執行緒進行讀操作的效率。ReadWriteLock可是實現併發讀。

     6)ReentrantLock和synchronized都是可重入鎖。

3、分散式鎖

    分散式鎖是防止多程序出現併發問題,所以不可以藉助記憶體來實現鎖的功能。但是可以藉助redis、memcached(Memcached 是一個高效能的分散式記憶體物件快取系統)、zookeeper實現。

1)zookeeper。每個客戶端對某個功能加鎖時,在zookeeper上的與該功能對應的指定節點的目錄下,生成一個唯一的瞬時有序節點。判斷是否獲取鎖的方式很簡單,只需要判斷有序節點中序號最小的一個。當釋放鎖的時候,只需將這個瞬時節點刪除即可。同時,其可以避免服務宕機導致的鎖無法釋放,而產生的死鎖問題。優點:鎖安全性高,zk可持久化。缺點:效能開銷比較高。因為其需要動態產生、銷燬瞬時節點來實現鎖功能。

2)memcached帶有add函式,利用add函式的特性即可實現分散式鎖。add和set的區別在於:如果多執行緒併發set,則每個set都會成功,但最後儲存的值以最後的set的執行緒為準。而add的話則相反,add會新增第一個到達的值,並返回true,後續的新增則都會返回false。利用該點即可很輕鬆地實現分散式鎖。優點:併發高效。缺點:memcached採用列入LRU置換策略,所以如果記憶體不夠,可能導致快取中的鎖資訊丟失。memcached無法持久化,一旦重啟,將導致資訊丟失。

3)可以使用jedis.set實現,並且設定過期時間,否則如果加完鎖出現故障就會導致死鎖。