前言
看了很多用
redisson
實現分布式鎖的博客, 對他們使用的方式我個人認為有一點點自己的看法, 接下來本文將以例子來驗證為什么會有誤解, 和看看正確的方式應該怎么寫?
本文源代碼: 源代碼下載
大多數認為的寫法
看到很多人都是這樣寫
RLock lock = redisson.getLock(KEY); lock.lock() // do your own work lock.unlock()
簡單看完源代碼后, 我看到該方法會去調用一個響應一個中斷的
lockInterruptibly
,此時我就有點疑惑了, 響應中斷就是表示線程如果發生中斷就不會在等待隊列中等待(當然redisson
是采用SUB/PUB
的方式),(本文不分析源碼哈,對該鎖的源碼分析會放到專門博客里面分析, 主要是驗證該如何使用)可以看下圖:
圖片.png
上圖中
lock
等方法會最終調用public void lockInterruptibly(long leaseTime, TimeUnit unit) throws InterruptedException
該方法會拋出異常, 然而lock
方法並沒有把這個異常拋出給使用者, 而是采用捕獲異常,並且重新設置中斷狀態.
這下就有點明白了, 是不是需要用戶自己來判斷當前線程的狀態來判斷當前線程是否獲得鎖了呢?已經猜到這一步了, 接下來就需要驗證一下自己的猜想
例子1:驗證上面的寫法
我是用
maven
項目構建的一個小項目,因此加入如下依賴
<dependency> <groupId>org.redisson</groupId> <artifactId>redisson</artifactId> <version>2.7.0</version> </dependency>
加入以下例子.
import org.redisson.Redisson; import org.redisson.api.RLock; import org.redisson.config.Config; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; public class TestDistributedRedisLock { private static CountDownLatch finish = new CountDownLatch(2); private static final String KEY = "testlock"; private static Config config; private static Redisson redisson; static { config = new Config(); config.useSingleServer().setAddress("127.0.0.1:6379"); redisson = (Redisson)Redisson.create(config); } public static void main(String[] args) { Thread thread_1 = new LockWithoutBoolean("thread-1"); Thread thread_2 = new LockWithoutBoolean("thread-2"); thread_1.start(); try { TimeUnit.SECONDS.sleep(10); // 睡10秒鍾 為了讓thread_1充分運行 thread_2.start(); TimeUnit.SECONDS.sleep(10); // 讓thread_2 等待鎖 thread_2.interrupt(); // 中斷正在等待鎖的thread_2 觀察thread_2是否會不會拿到鎖 finish.await(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } finally { redisson.shutdown(); } } static class LockWithoutBoolean extends Thread { private String name; public LockWithoutBoolean(String name) { super(name); } public void run() { RLock lock = redisson.getLock(KEY); lock.lock(10, TimeUnit.MINUTES); System.out.println(Thread.currentThread().getName() + " gets lock. and interrupt: " + Thread