From 1bf9dd1217ad2d62cb6e23ea40e2a56395a9f2b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=9A=84=E7=8B=AE=E5=AD=90li?= <15040126243@163.com> Date: Thu, 10 Jun 2021 13:32:50 +0800 Subject: [PATCH] =?UTF-8?q?update=20=E4=BC=98=E5=8C=96redis=E9=94=81?= =?UTF-8?q?=E5=B7=A5=E5=85=B7=E4=BB=A3=E7=A0=81=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/core/redis/RedisLockManager.java | 109 +++++++++++++----- .../demo/controller/RedisLockController.java | 2 +- .../framework/aspectj/RedisLockAspect.java | 3 +- 3 files changed, 79 insertions(+), 35 deletions(-) diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisLockManager.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisLockManager.java index fb665a99..e00f8009 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisLockManager.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisLockManager.java @@ -22,15 +22,50 @@ public class RedisLockManager { @Autowired private RedissonClient redissonClient; - private final ThreadLocal threadLocal = new ThreadLocal<>(); + /** + * 通用锁 + */ + private final static Integer BASE_LOCK = 1; + + /** + * 公平锁 + */ + private final static Integer FAIR_LOCK = 2; + + /** + * 计数锁 + */ + private final static Integer COUNT_LOCK = 3; + + /** + * 存放当前线程获取锁的类型 + */ + private final ThreadLocal threadLocal = new ThreadLocal<>(); + + /** + * 获取锁 + */ + private T getLock(String key, Integer lockType) { + Assert.isTrue(StrUtil.isNotBlank(key), "key不能为空"); + threadLocal.set(lockType); + Object lock; + if (BASE_LOCK.equals(lockType)) { + lock = redissonClient.getLock(key); + } else if (FAIR_LOCK.equals(lockType)) { + lock = redissonClient.getFairLock(key); + } else if (COUNT_LOCK.equals(lockType)) { + lock = redissonClient.getCountDownLatch(key); + } else { + throw new RuntimeException("锁不存在!"); + } + return (T)lock; + } /** * 获取锁(不用设置超时时间,一直等待) */ public boolean getLock(String key) { - Assert.isTrue(StrUtil.isNotBlank(key), "key不能为空"); - RLock lock = redissonClient.getLock(key); - threadLocal.set(lock); + RLock lock = getLock(key, BASE_LOCK); return lock.tryLock(); } @@ -41,13 +76,16 @@ public class RedisLockManager { * @param time 过期时间 * @param expireUnit 时间单位 */ - public boolean getLock(String key, long time, TimeUnit expireUnit) throws InterruptedException { - Assert.isTrue(StrUtil.isNotBlank(key), "key不能为空"); + public boolean getLock(String key, long time, TimeUnit expireUnit) { Assert.isTrue(time > 0, "过期时间必须大于0"); Assert.isTrue(Validator.isNotEmpty(expireUnit), "时间单位不能为空"); - RLock lock = redissonClient.getLock(key); - threadLocal.set(lock); - return lock.tryLock(time, expireUnit); + RLock lock = getLock(key, BASE_LOCK); + try { + return lock.tryLock(time, expireUnit); + } catch (InterruptedException e) { + e.printStackTrace(); + return false; + } } /** @@ -57,28 +95,30 @@ public class RedisLockManager { * @param waitTime 获取锁等待时间 * @param leaseTime 保留锁的时间 * @param expireUnit 时间单位 - * @throws InterruptedException */ - public boolean getLock(String key, long waitTime, long leaseTime, TimeUnit expireUnit) throws InterruptedException { - Assert.isTrue(StrUtil.isNotBlank(key), "key不能为空"); + public boolean getLock(String key, long waitTime, long leaseTime, TimeUnit expireUnit) { Assert.isTrue(waitTime > 0, "获取锁等待时间必须大于0"); Assert.isTrue(leaseTime > 0, "保留锁的时间必须大于0"); Assert.isTrue(Validator.isNotEmpty(expireUnit), "时间单位不能为空"); - RLock lock = redissonClient.getLock(key); - threadLocal.set(lock); - return lock.tryLock(waitTime, leaseTime, expireUnit); + RLock lock = getLock(key, BASE_LOCK); + try { + return lock.tryLock(waitTime, leaseTime, expireUnit); + } catch (InterruptedException e) { + e.printStackTrace(); + return false; + } } + /** * 获取计数器锁 * * @param key * @param count countDownLatch 的数量 */ - public RCountDownLatch countDownLatch(String key, long count) { - Assert.isTrue(StrUtil.isNotBlank(key), "key不能为空"); + public RCountDownLatch getCountDownLatch(String key, long count) { Assert.isTrue(count >= 0, "count数量必须大于等于0"); - RCountDownLatch rCountDownLatch = redissonClient.getCountDownLatch(key); + RCountDownLatch rCountDownLatch = getLock(key, COUNT_LOCK); rCountDownLatch.trySetCount(count); return rCountDownLatch; } @@ -93,14 +133,17 @@ public class RedisLockManager { * @return * @throws InterruptedException */ - public boolean getFairLock(String key, long waitTime, long leaseTime, TimeUnit expireUnit) throws InterruptedException { - Assert.isTrue(StrUtil.isNotBlank(key), "key不能为空"); + public boolean getFairLock(String key, long waitTime, long leaseTime, TimeUnit expireUnit) { Assert.isTrue(waitTime > 0, "获取锁等待时间必须大于0"); Assert.isTrue(leaseTime > 0, "保留锁的时间必须大于0"); Assert.isTrue(Validator.isNotEmpty(expireUnit), "时间单位不能为空"); - RLock lock = redissonClient.getFairLock(key); - threadLocal.set(lock); - return lock.tryLock(waitTime, leaseTime, expireUnit); + RLock lock = getLock(key, FAIR_LOCK); + try { + return lock.tryLock(waitTime, leaseTime, expireUnit); + } catch (InterruptedException e) { + e.printStackTrace(); + return false; + } } /** @@ -109,23 +152,25 @@ public class RedisLockManager { * @param key * @param leaseTime 持有锁的时间 * @param expireUnit 时间单位 - * @return - * @throws InterruptedException */ - public boolean getFairLock(String key, long leaseTime, TimeUnit expireUnit) throws InterruptedException { - Assert.isTrue(StrUtil.isNotBlank(key), "key不能为空"); + public boolean getFairLock(String key, long leaseTime, TimeUnit expireUnit) { Assert.isTrue(leaseTime > 0, "保留锁的时间必须大于0"); Assert.isTrue(Validator.isNotEmpty(expireUnit), "时间单位不能为空"); - RLock lock = redissonClient.getFairLock(key); - threadLocal.set(lock); - return lock.tryLock(leaseTime, expireUnit); + RLock lock = getLock(key, FAIR_LOCK); + try { + return lock.tryLock(leaseTime, expireUnit); + } catch (InterruptedException e) { + e.printStackTrace(); + return false; + } } /** * 释放锁(统一释放) */ - public void unLock() { - RLock lock = threadLocal.get(); + public void unLock(String key) { + Integer lockType = threadLocal.get(); + RLock lock = getLock(key, lockType); lock.unlock(); threadLocal.remove(); } diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisLockController.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisLockController.java index 40019fc2..e80e3d6b 100644 --- a/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisLockController.java +++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisLockController.java @@ -52,7 +52,7 @@ public class RedisLockController { if (flag) { log.info("获取锁成功: " + key); Thread.sleep(3000); - redisLockManager.unLock(); + redisLockManager.unLock(key); log.info("释放锁成功: " + key); } else { log.error("获取锁失败: " + key); diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/RedisLockAspect.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/RedisLockAspect.java index 9d3bc8d9..efe628f3 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/RedisLockAspect.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/RedisLockAspect.java @@ -10,7 +10,6 @@ import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; -import org.redisson.api.RLock; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @@ -78,7 +77,7 @@ public class RedisLockAspect { } catch (Exception e) { throw new RuntimeException(e); } finally { - redisLockManager.unLock(); + redisLockManager.unLock(key); log.info("unlock => key : " + key + " , ThreadName : " + Thread.currentThread().getName()); } } else {