當前位置:
首頁 >
前端技术
> javascript
>内容正文
javascript
SpringBoot Redis分布式锁
生活随笔
收集整理的這篇文章主要介紹了
SpringBoot Redis分布式锁
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
maven依賴
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.16.14</version> </dependency>?
幫助類 采用redis的setNX實現
- SETNX(SET If Not Exists):當且僅當 Key 不存在時,則可以設置,否則不做任何動作。
?
package com.whq.test;import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.core.ValueOperations; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils;import java.util.concurrent.TimeUnit;@Component @Slf4j public class DistributedLockHelper {private final static long LOCK_EXPIRE = 30 * 1000L;//單個業務持有鎖的時間30s,防止死鎖private final static long LOCK_TRY_INTERVAL = 30L;//默認30ms嘗試一次private final static long LOCK_TRY_TIMEOUT = 20 * 1000L;//默認嘗試20s@Autowiredprivate StringRedisTemplate stringRedisTemplate;/*** 嘗試獲取全局鎖** @param key 鎖的名稱* @return true 獲取成功,false獲取失敗*/public boolean tryLock(String key) {return getLock(key, LOCK_TRY_TIMEOUT, LOCK_TRY_INTERVAL, LOCK_EXPIRE);}/*** 嘗試獲取全局鎖** @param key 鎖的名稱* @param timeout 獲取超時時間 單位ms* @return true 獲取成功,false獲取失敗*/public boolean tryLock(String key, long timeout) {return getLock(key, timeout, LOCK_TRY_INTERVAL, LOCK_EXPIRE);}/*** 嘗試獲取全局鎖** @param key 鎖的名稱* @param timeout 獲取鎖的超時時間* @param tryInterval 多少毫秒嘗試獲取一次* @return true 獲取成功,false獲取失敗*/public boolean tryLock(String key, long timeout, long tryInterval) {return getLock(key, timeout, tryInterval, LOCK_EXPIRE);}/*** 嘗試獲取全局鎖** @param key 鎖的名稱* @param timeout 獲取鎖的超時時間* @param tryInterval 多少毫秒嘗試獲取一次* @param lockExpireTime 鎖的過期* @return true 獲取成功,false獲取失敗*/public boolean tryLock(String key, long timeout, long tryInterval, long lockExpireTime) {return getLock(key, timeout, tryInterval, lockExpireTime);}/*** 操作redis獲取全局鎖** @param key 鎖的名稱* @param timeout 獲取的超時時間* @param tryInterval 多少ms嘗試一次* @param lockExpireTime 獲取成功后鎖的過期時間* @return true 獲取成功,false獲取失敗*/public boolean getLock(String key, long timeout, long tryInterval, long lockExpireTime) {try {if (StringUtils.isEmpty(key)) {return false;}long startTime = System.currentTimeMillis();while(true){if (!stringRedisTemplate.hasKey(key)) {ValueOperations<String, String> ops = stringRedisTemplate.opsForValue();if(ops.setIfAbsent(key, "", lockExpireTime, TimeUnit.MILLISECONDS)) {return true;}} else {//存在鎖log.debug("lock is exist!!!");}if (System.currentTimeMillis() - startTime > timeout) {//嘗試超過了設定值之后直接跳出循環return false;}Thread.sleep(tryInterval);}} catch (InterruptedException e) {log.error(e.getMessage());return false;}}/*** 釋放鎖*/public void releaseLock(String key) {if (!StringUtils.isEmpty(key)) {stringRedisTemplate.delete(key);}}}調用測試
?
@RestController @SpringBootApplication @Slf4j public class TestApplication {public static void main(String[] args) {SpringApplication.run(TestApplication.class, args);}@Autowiredprivate DistributedLockHelper distributedLockHandler;@RequestMapping("lock")public String lock(){String key="testlock";log.info("準備獲取鎖");if(distributedLockHandler.tryLock(key)){try {//為了演示鎖的效果,這里睡眠5000毫秒log.info("已經獲取到鎖");Thread.sleep(5000);}catch (Exception e){e.printStackTrace();}distributedLockHandler.releaseLock(key);log.info("鎖已釋放");}return "hello world!";} }配置application.yml
server:port: 18081spring:redis:host: 10.0.197.189port: 6379?
注意:測試時要采用兩個瀏覽器,或者一個用ip、一個用localhost訪問,否則瀏覽器會同時只能進行一個請求。
測試輸出日志
?
2019-07-23 14:42:52 1997495 [http-nio-18081-exec-1] INFO com.whq.test.TestApplication - 準備獲取鎖 2019-07-23 14:42:52 1997507 [http-nio-18081-exec-1] INFO com.whq.test.TestApplication - 已經獲取到鎖 2019-07-23 14:42:53 1998452 [http-nio-18081-exec-3] INFO com.whq.test.TestApplication - 準備獲取鎖 2019-07-23 14:42:57 2002510 [http-nio-18081-exec-1] INFO com.whq.test.TestApplication - 鎖已釋放 2019-07-23 14:42:57 2002530 [http-nio-18081-exec-3] INFO com.whq.test.TestApplication - 已經獲取到鎖 2019-07-23 14:43:02 2007535 [http-nio-18081-exec-3] INFO com.whq.test.TestApplication - 鎖已釋放?
總結
以上是生活随笔為你收集整理的SpringBoot Redis分布式锁的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux命令之ifconfig
- 下一篇: Java 查询Word是否存在关键字,并