Redisson分布式閉鎖RCountDownLatch的使用詳細講解
本篇文章基于redisson-3.17.6版本源碼進行分析
一、RCountDownLatch的使用
RCountDownLatch的功能跟CountDownLatch,用于實現(xiàn)某個線程需要等待其他線程都完成之后,我再去執(zhí)行,這種場景就可以使用CountDownLatch。
@Test
public void testRCountDownLatch() {
Config config = new Config();
config.useSingleServer().setAddress("redis://127.0.0.1:6379");
RedissonClient redissonClient = Redisson.create(config);
RCountDownLatch rCountDownLatch = redissonClient.getCountDownLatch("anyCountDownLatch");
rCountDownLatch.trySetCount(5);
for (int i = 1; i <= 5; i++) {
new Thread(() -> {
System.out.println(Thread.currentThread().getName() + "離開教師...");
rCountDownLatch.countDown();
}, "A" + i).start();
}
try {
rCountDownLatch.await();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("班長鎖門...");
}A1離開教師...
A2離開教師...
A4離開教師...
A3離開教師...
A5離開教師...
班長鎖門...
二、trySetCount()設置計數(shù)器
/** * 僅當先前的計數(shù)已達到零或根本未設置時才設置新的計數(shù)值。 */ boolean trySetCount(long count);
public RFuture<Boolean> trySetCountAsync(long count) {
return commandExecutor.evalWriteAsync(getRawName(), LongCodec.INSTANCE, RedisCommands.EVAL_BOOLEAN,
// 往redis中寫入一個String類型的數(shù)據(jù) anyCountDownLatch:5
"if redis.call('exists', KEYS[1]) == 0 then "
+ "redis.call('set', KEYS[1], ARGV[2]); "
+ "redis.call('publish', KEYS[2], ARGV[1]); "
+ "return 1 "
+ "else "
+ "return 0 "
+ "end",
Arrays.asList(getRawName(), getChannelName()), CountDownLatchPubSub.NEW_COUNT_MESSAGE, count);
}同樣,在redis中寫入了一個{key}:{計數(shù)器總數(shù)}的String類型的數(shù)據(jù)。
三、countDown()源碼
減少鎖存器的計數(shù)器。當計數(shù)達到零時通知所有等待線程。
public RFuture<Void> countDownAsync() {
return commandExecutor.evalWriteNoRetryAsync(getRawName(), LongCodec.INSTANCE, RedisCommands.EVAL_BOOLEAN,
// 減少redis中計數(shù)器的值
"local v = redis.call('decr', KEYS[1]);" +
// 計數(shù)器減為0后,刪除對應的key
"if v <= 0 then redis.call('del', KEYS[1]) end;" +
"if v == 0 then redis.call('publish', KEYS[2], ARGV[1]) end;",
Arrays.<Object>asList(getRawName(), getChannelName()), CountDownLatchPubSub.ZERO_COUNT_MESSAGE);
}四、await()源碼
等到計數(shù)器達到零。
public void await() throws InterruptedException {
// 如果計數(shù)器為0,直接返回
if (getCount() == 0) {
return;
}
// 訂閱redisson_countdownlatch__channel__{anyCountDownLatch}的消息
CompletableFuture<RedissonCountDownLatchEntry> future = subscribe();
RedissonCountDownLatchEntry entry = commandExecutor.getInterrupted(future);
try {
// 不斷循環(huán)判斷計數(shù)器的值是否大于0,大于0說明還有線程沒執(zhí)行完成,在這里阻塞:LockSupport.park(this)
while (getCount() > 0) {
// waiting for open state
entry.getLatch().await();
}
} finally {
unsubscribe(entry);
}
}到此這篇關于Redisson分布式閉鎖RCountDownLatch的使用詳細講解的文章就介紹到這了,更多相關Redisson RCountDownLatch內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Spring Boot分段處理List集合多線程批量插入數(shù)據(jù)的解決方案
大數(shù)據(jù)量的List集合,需要把List集合中的數(shù)據(jù)批量插入數(shù)據(jù)庫中,本文給大家介紹Spring Boot分段處理List集合多線程批量插入數(shù)據(jù)的解決方案,感興趣的朋友跟隨小編一起看看吧2024-04-04
Java/Android 實現(xiàn)簡單的HTTP服務器
這篇文章主要介紹了Java/Android 如何實現(xiàn)簡單的HTTP服務器,幫助大家更好的進行功能測試,感興趣的朋友可以了解下2020-10-10
Netty分布式ByteBuf中PooledByteBufAllocator剖析
這篇文章主要為大家介紹了Netty分布式ByteBuf剖析PooledByteBufAllocator簡述,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-03-03
SpringBoot簡單使用SpringData的jdbc和durid
今天給大家?guī)淼氖顷P于Java的相關知識,文章圍繞著SpringBoot簡單使用SpringData的jdbc和durid,文中有非常詳細的介紹及代碼示例,需要的朋友可以參考下2021-06-06
vue+springboot讀取git的markdown文件并展示功能
Markdown-it 是一個用于解析和渲染 Markdown 標記語言的 JavaScript 庫,使用 Markdown-it,你可以將 Markdown 文本解析為 HTML 輸出,并且可以根據(jù)需要添加功能、擴展語法或修改解析行為,本文介紹vue+springboot讀取git的markdown文件并展示,感興趣的朋友一起看看吧2024-01-01
Java使用NIO包實現(xiàn)Socket通信的實例代碼
本篇文章主要介紹了Java使用NIO包實現(xiàn)Socket通信的實例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-02-02
Spring?Data?JPA系列QueryByExampleExecutor使用詳解
這篇文章主要為大家介紹了Spring?Data?JPA系列QueryByExampleExecutor使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-09-09

