From 48783db422525548d7eec5caba788f8ab53d7bec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B9=A6=E4=B8=AD=E8=87=AA=E6=9C=89=E9=A2=9C=E5=A6=82?= =?UTF-8?q?=E7=8E=89?= <1206770390@qq.com> Date: Sat, 26 Jul 2025 15:00:48 +0000 Subject: [PATCH] =?UTF-8?q?feat(cache/redisson):=20=E6=96=B0=E5=A2=9E=20Re?= =?UTF-8?q?disLockUtils=20Redisson=20=E5=88=86=E5=B8=83=E5=BC=8F=E9=94=81?= =?UTF-8?q?=E5=B7=A5=E5=85=B7=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cache/redisson/util/RedisLockUtils.java | 191 ++++++++++++++++++ .../cache/redisson/util/RedisUtils.java | 41 +++- 2 files changed, 230 insertions(+), 2 deletions(-) create mode 100644 continew-starter-cache/continew-starter-cache-redisson/src/main/java/top/continew/starter/cache/redisson/util/RedisLockUtils.java diff --git a/continew-starter-cache/continew-starter-cache-redisson/src/main/java/top/continew/starter/cache/redisson/util/RedisLockUtils.java b/continew-starter-cache/continew-starter-cache-redisson/src/main/java/top/continew/starter/cache/redisson/util/RedisLockUtils.java new file mode 100644 index 00000000..92d48e03 --- /dev/null +++ b/continew-starter-cache/continew-starter-cache-redisson/src/main/java/top/continew/starter/cache/redisson/util/RedisLockUtils.java @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. + *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *
+ * http://www.gnu.org/licenses/lgpl.html + *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package top.continew.starter.cache.redisson.util;
+
+import org.redisson.api.RLock;
+import org.redisson.api.RedissonClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import top.continew.starter.core.util.SpringUtils;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Redisson分布式锁 工具类
+ *
+ * @author lishuyan
+ */
+public class RedisLockUtils implements AutoCloseable {
+
+ private static final Logger log = LoggerFactory.getLogger(RedisLockUtils.class);
+
+ /**
+ * 默认锁过期时间(毫秒)
+ */
+ private static final long DEFAULT_EXPIRE_TIME = 10000L;
+
+ /**
+ * 默认获取锁超时时间(毫秒)
+ */
+ private static final long DEFAULT_TIMEOUT = 5000L;
+
+ /**
+ * Redisson 客户端
+ */
+ private static volatile RedissonClient CLIENT;
+
+ /**
+ * 锁实例
+ */
+ private final RLock lock;
+
+ /**
+ * 是否成功获取锁
+ */
+ private boolean isLocked;
+
+ /**
+ * 获取Redisson客户端实例
+ *
+ * @return RedissonClient实例
+ */
+ private static RedissonClient getClient() {
+ if (CLIENT == null) {
+ synchronized (RedisLockUtils.class) {
+ if (CLIENT == null) {
+ CLIENT = SpringUtils.getBean(RedissonClient.class, false);
+ }
+ }
+ }
+ return CLIENT;
+ }
+
+ /**
+ * 私有构造函数,防止外部实例化
+ */
+ private RedisLockUtils(RLock lock, long expireTime, long timeout, TimeUnit unit) {
+ this.lock = lock;
+ try {
+ this.isLocked = lock.tryLock(timeout, expireTime, unit);
+ if (isLocked) {
+ log.debug("获取锁成功,key: {}", lock.getName());
+ } else {
+ log.debug("获取锁失败,key: {}", lock.getName());
+ }
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ log.error("获取锁过程中被中断,key: {}", lock.getName(), e);
+ }
+ }
+
+ /**
+ * 尝试获取锁(启用看门狗自动续期机制)
+ *
+ * @param key 锁的键
+ * @param timeout 获取锁的超时时间
+ * @param unit 时间单位
+ * @return LockUtils 实例
+ */
+ public static RedisLockUtils tryLockWithWatchdog(String key, long timeout, TimeUnit unit) {
+ RLock lock = getClient().getLock(key);
+ // 传入-1表示使用看门狗机制
+ return new RedisLockUtils(lock, -1, timeout, unit);
+ }
+
+ /**
+ * 尝试获取锁(启用看门狗自动续期机制,默认时间单位为毫秒)
+ *
+ * @param key 锁的键
+ * @param timeout 获取锁的超时时间(单位:毫秒)
+ * @return LockUtils 实例
+ */
+ public static RedisLockUtils tryLockWithWatchdog(String key, long timeout) {
+ return tryLockWithWatchdog(key, timeout, TimeUnit.MILLISECONDS);
+ }
+
+ /**
+ * 尝试获取锁(启用看门狗自动续期机制,使用默认超时时间)
+ *
+ * @param key 锁的键
+ * @return LockUtils 实例
+ */
+ public static RedisLockUtils tryLockWithWatchdog(String key) {
+ return tryLockWithWatchdog(key, DEFAULT_TIMEOUT);
+ }
+
+ /**
+ * 尝试获取锁
+ *
+ * @param key 锁的键
+ * @param expireTime 锁的过期时间
+ * @param timeout 获取锁的超时时间
+ * @param unit 时间单位
+ * @return LockUtils 实例
+ */
+ public static RedisLockUtils tryLock(String key, long expireTime, long timeout, TimeUnit unit) {
+ RLock lock = getClient().getLock(key);
+ return new RedisLockUtils(lock, expireTime, timeout, unit);
+ }
+
+ /**
+ * 尝试获取锁(默认时间单位为毫秒)
+ *
+ * @param key 锁的键
+ * @param expireTime 锁的过期时间(单位:毫秒)
+ * @param timeout 获取锁的超时时间(单位:毫秒)
+ * @return LockUtils 实例
+ */
+ public static RedisLockUtils tryLock(String key, long expireTime, long timeout) {
+ return tryLock(key, expireTime, timeout, TimeUnit.MILLISECONDS);
+ }
+
+ /**
+ * 尝试获取锁(使用默认过期时间和超时时间)
+ *
+ * @param key 锁的键
+ * @return LockUtils 实例
+ */
+ public static RedisLockUtils tryLock(String key) {
+ return tryLock(key, DEFAULT_EXPIRE_TIME, DEFAULT_TIMEOUT);
+ }
+
+ /**
+ * 检查是否成功获取锁
+ *
+ * @return true:成功;false:失败
+ */
+ public boolean isLocked() {
+ return isLocked;
+ }
+
+ /**
+ * 释放锁
+ */
+ @Override
+ public void close() {
+ if (isLocked && lock.isHeldByCurrentThread()) {
+ try {
+ lock.unlockAsync().get();
+ log.debug("释放锁成功,key: {}", lock.getName());
+ } catch (Exception e) {
+ log.error("释放锁失败,key: {}", lock.getName(), e);
+ }
+ } else {
+ log.debug("锁未被当前线程持有,无需释放,key: {}", lock.getName());
+ }
+ }
+}
diff --git a/continew-starter-cache/continew-starter-cache-redisson/src/main/java/top/continew/starter/cache/redisson/util/RedisUtils.java b/continew-starter-cache/continew-starter-cache-redisson/src/main/java/top/continew/starter/cache/redisson/util/RedisUtils.java
index b522441f..335e06ad 100644
--- a/continew-starter-cache/continew-starter-cache-redisson/src/main/java/top/continew/starter/cache/redisson/util/RedisUtils.java
+++ b/continew-starter-cache/continew-starter-cache-redisson/src/main/java/top/continew/starter/cache/redisson/util/RedisUtils.java
@@ -28,6 +28,7 @@ import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
+import java.util.function.Consumer;
/**
* Redis 工具类
@@ -51,6 +52,42 @@ public class RedisUtils {
return CLIENT;
}
+ /**
+ * 发布消息
+ *
+ * @param name 主题名称
+ * @param msg 发送数据
+ * @param consumer 自定义处理
+ */
+ public static 如果键不存在,则不设置 如果键不存在,则不设置