redisson.tryLock()參數的使用及理解
因為redis的 setnx 還是有諸多問題,這里使用redisson,當然,正常來說,redis的setnx已經夠用了
- 可重入鎖問題
- 超時釋放問題
- 如果是集群 主從不一致問題
依賴
<dependency> <groupId>org.redisson</groupId> <artifactId>redisson</artifactId> <version>3.13.6</version> </dependency>
配置
package com.hmdp.config; import com.baomidou.mybatisplus.annotation.DbType; import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; import org.redisson.Redisson; import org.redisson.api.RedissonClient; import org.redisson.config.Config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class RedissonConfig { @Bean public RedissonClient redissonClient(){ Config config = new Config(); config.useSingleServer().setAddress("redis://127.0.0.1:6379"); // config.useSingleServer().setAddress("redis://127.0.0.1:6379").setPassword("123456"); return Redisson.create(config); } }
使用
package com.hmdp; import com.hmdp.entity.SeckillVoucher; import com.hmdp.service.ISeckillVoucherService; import com.hmdp.service.impl.SeckillVoucherServiceImpl; import org.junit.Test; import org.junit.jupiter.api.BeforeEach; import org.redisson.api.RLock; import org.redisson.api.RedissonClient; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import javax.annotation.Resource; @SpringBootTest public class HmDianPingApplicationTests { @Resource private RedissonClient redissonClient; @Test public void testRedisson() { long shopId = 147852478L; /*這樣獲取的是一把 可重入鎖*/ RLock lock = redissonClient.getLock("lock:order:" + shopId); /*等待時間,超時施放時間,時間單位 * 不傳遞參數默認值是:不等待(-1),30秒*/ boolean b = lock.tryLock(); if (!b) { System.out.println("獲取鎖失敗"); } try{ System.out.println("執(zhí)行業(yè)務邏輯"); }finally { lock.unlock(); } } }
這里有三個參數
- waitTime ----等待時間
- leaseTime ----超時施放時間
- TimeUnit ----時間單位
等待時間
如果ABC…多個線程去搶奪一把鎖,A成功了,如果設置的是 -1,那么BCD。。。。就不等待,直接返回失敗,也就是不再去搶奪鎖了,一次失敗,直接放棄。
如果不是-1,假如說是 10(單位是秒)那么BCD…失敗后會擇機再次去搶奪,這里的擇機搶奪,就代表著不是 與A搶奪失敗后的立馬再次搶奪,因為【明知道A搶過鎖之后會執(zhí)行自己的業(yè)務,需要一定的時間,那么
BCD。。。立馬再去搶奪鎖的意義在哪里呢? 除了徒增cpu的負擔,沒有太大意義】 。所以這里的擇機搶奪,其實是利用了 發(fā)布,訂閱機制。
從上面的圖片可以看到,A搶過鎖之后,執(zhí)行業(yè)務,結束之后釋放鎖,釋放鎖的時候還 publish (發(fā)布)了一個信號,而有人發(fā)布,就有人訂閱,發(fā)布人是A,訂閱人是BCD…,所以說這里的擇機再次搶奪是在BCD…接收到A發(fā)布的消息之后再去搶奪。
當然了,從第一次與A搶奪失敗,到等待A完成業(yè)務發(fā)布消息這段等待時間+ 第一次和A搶奪鎖的時間 總數不能超過10s,畢竟10s 就是硬性規(guī)定,10s之內,不論發(fā)生多么復雜的邏輯,只要拿到鎖就行,不行就直接放棄。
超時施放時間
就是說 A拿到了鎖之后, 如果發(fā)生了一些異常錯誤,內部業(yè)務沒能正常的執(zhí)行,沒能正常執(zhí)行釋放鎖的操作,這個時候 這個超時施放時間才會起作用,也就是說,在A搶到鎖之后,即便A的業(yè)務出現了堵塞,但是只要沒發(fā)生一些異常情況,這里的超時施放時間是不起作用的,因為只要不發(fā)生異常,內部就會有一個 看門狗,每隔 超時施放時間/3就會刷新一次鎖的過期時間(是一個定時任務),確保A能夠執(zhí)行完成業(yè)務,當然,A執(zhí)行完業(yè)務后,會刪除刷新有效期的定時任務。
所以說,超時釋放時間在正常執(zhí)行業(yè)務的時候,是不發(fā)揮作用的,只在出現異常的時候才會起作用。
總結
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
使用Spring Security OAuth2實現單點登錄
在本教程中,我們將討論如何使用Spring Security OAuth和Spring Boot實現SSO - 單點登錄。感興趣的朋友跟隨小編一起看看吧2019-06-06Java下載遠程服務器文件到本地(基于http協(xié)議和ssh2協(xié)議)
這篇文章主要介紹了Java下載遠程服務器文件到本地的方法(基于http協(xié)議和ssh2協(xié)議),幫助大家更好的理解和使用Java,感興趣的朋友可以了解下2021-01-01MyBatisPlus 一對多、多對一、多對多的完美解決方案
這篇文章主要介紹了MyBatisPlus 一對多、多對一、多對多的完美解決方案,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-11-11JSP request.setAttribute()詳解及實例
這篇文章主要介紹了 javascript request.setAttribute()詳解及實例的相關資料,需要的朋友可以參考下2017-02-02