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

普通鎖和分布式鎖

異常 set 宕機 keep tran 還在 重啟 per cache

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實現,並且設置過期時間,否則如果加完鎖出現故障就會導致死鎖。

普通鎖和分布式鎖