|
@@ -1,5 +1,6 @@
|
|
|
package com.fdkankan.redis.util;
|
|
|
|
|
|
+import cn.hutool.core.thread.ThreadUtil;
|
|
|
import cn.hutool.core.util.StrUtil;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
@@ -27,17 +28,31 @@ public class RedisLockUtil {
|
|
|
|
|
|
/**
|
|
|
* 加锁,自旋重试三次
|
|
|
+ * 默认以线程id作为锁的值
|
|
|
*
|
|
|
* @param lockKey 锁key
|
|
|
* @param expireTime 锁过期时间 单位 毫秒
|
|
|
* @return
|
|
|
*/
|
|
|
public boolean lock(String lockKey, int expireTime) {
|
|
|
+ return this.lock(lockKey, null, expireTime);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 加锁,自旋重试三次
|
|
|
+ * @param lockKey 锁key
|
|
|
+ * @param lockVal 锁value
|
|
|
+ * @param expireTime 锁过期时间 单位 毫秒
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public boolean lock(String lockKey, String lockVal, int expireTime) {
|
|
|
boolean locked = false;
|
|
|
int tryCount = 3;
|
|
|
- String threadId = String.valueOf(Thread.currentThread().getId());
|
|
|
+ if(lockVal == null){
|
|
|
+ lockVal = String.valueOf(Thread.currentThread().getId());
|
|
|
+ }
|
|
|
while (tryCount > 0) {
|
|
|
- locked = redisTemplate.opsForValue().setIfAbsent(lockKey, threadId, expireTime, TimeUnit.SECONDS);
|
|
|
+ locked = redisTemplate.opsForValue().setIfAbsent(lockKey, lockVal, expireTime, TimeUnit.SECONDS);
|
|
|
if(locked){
|
|
|
return locked;
|
|
|
}
|
|
@@ -45,7 +60,7 @@ public class RedisLockUtil {
|
|
|
try {
|
|
|
Thread.sleep(300);
|
|
|
} catch (InterruptedException e) {
|
|
|
- log.error("线程被中断[线程id:" + threadId + "]", e);
|
|
|
+ e.printStackTrace();
|
|
|
}
|
|
|
}
|
|
|
return locked;
|
|
@@ -69,21 +84,41 @@ public class RedisLockUtil {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
+ * 非原子解锁,可能解别人锁,不安全
|
|
|
+ *
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public boolean unlock(String lockKey, String lockVal) {
|
|
|
+ return this.unlock(lockKey, null);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
* 使用lua脚本解锁,不会解除别人锁
|
|
|
*
|
|
|
* @param
|
|
|
* @return
|
|
|
*/
|
|
|
public boolean unlockLua(String lockKey) {
|
|
|
- String threadId = String.valueOf(Thread.currentThread().getId());
|
|
|
- if (StrUtil.isEmpty(lockKey) || Objects.isNull(threadId))
|
|
|
+ return this.unlockLua(lockKey, null);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 使用lua脚本解锁,不会解除别人锁
|
|
|
+ *
|
|
|
+ * @param
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public boolean unlockLua(String lockKey, String lockVal) {
|
|
|
+ if(lockVal == null){
|
|
|
+ lockVal = String.valueOf(Thread.currentThread().getId());
|
|
|
+ }
|
|
|
+ if (StrUtil.isEmpty(lockKey) || Objects.isNull(lockVal))
|
|
|
return false;
|
|
|
DefaultRedisScript<Long> redisScript = new DefaultRedisScript();
|
|
|
-// redisScript.setLocation(new ClassPathResource("unlock.lua"));
|
|
|
redisScript.setScriptText(UNLOCK_LUA);
|
|
|
redisScript.setResultType(Long.class);
|
|
|
|
|
|
- Object result = redisTemplate.execute(redisScript, Arrays.asList(lockKey), threadId);
|
|
|
+ Object result = redisTemplate.execute(redisScript, Arrays.asList(lockKey), lockVal);
|
|
|
return result.equals(Long.valueOf(1));
|
|
|
}
|
|
|
|