|
@@ -1,7 +1,9 @@
|
|
|
package com.fdkankan.redis.util;
|
|
|
|
|
|
+import cn.hutool.core.lang.UUID;
|
|
|
import cn.hutool.core.thread.ThreadUtil;
|
|
|
import cn.hutool.core.util.StrUtil;
|
|
|
+import java.util.concurrent.ConcurrentHashMap;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.data.redis.core.RedisTemplate;
|
|
@@ -16,6 +18,8 @@ import java.util.concurrent.TimeUnit;
|
|
|
@Slf4j
|
|
|
public class RedisLockUtil {
|
|
|
|
|
|
+ private ConcurrentHashMap<String, String> THREADID_LOCKVAL_MAP = new ConcurrentHashMap<>();
|
|
|
+
|
|
|
@Autowired
|
|
|
private RedisTemplate redisTemplate;
|
|
|
|
|
@@ -48,12 +52,20 @@ public class RedisLockUtil {
|
|
|
public boolean lock(String lockKey, String lockVal, int expireTime) {
|
|
|
boolean locked = false;
|
|
|
int tryCount = 3;
|
|
|
+ String threadId = null;
|
|
|
+ String uuid = null;
|
|
|
if(lockVal == null){
|
|
|
- lockVal = String.valueOf(Thread.currentThread().getId());
|
|
|
+ threadId = String.valueOf(Thread.currentThread().getId());
|
|
|
+ uuid = UUID.randomUUID().toString();
|
|
|
+ lockVal = uuid + ":" + threadId;
|
|
|
+ log.info("加锁lockval:{}",lockVal);
|
|
|
}
|
|
|
while (tryCount > 0) {
|
|
|
locked = redisTemplate.opsForValue().setIfAbsent(lockKey, lockVal, expireTime, TimeUnit.SECONDS);
|
|
|
if(locked){
|
|
|
+ if(threadId != null){
|
|
|
+ THREADID_LOCKVAL_MAP.put(threadId, lockVal);
|
|
|
+ }
|
|
|
return locked;
|
|
|
}
|
|
|
tryCount--;
|
|
@@ -72,15 +84,7 @@ public class RedisLockUtil {
|
|
|
* @return
|
|
|
*/
|
|
|
public boolean unlock(String lockKey) {
|
|
|
- String threadId = String.valueOf(Thread.currentThread().getId());
|
|
|
- if (StrUtil.isEmpty(lockKey) || Objects.isNull(threadId))
|
|
|
- return false;
|
|
|
- boolean releaseLock = false;
|
|
|
- Long val = (Long) redisTemplate.opsForValue().get(lockKey);
|
|
|
- if (threadId.equals(val)) {
|
|
|
- releaseLock = redisTemplate.delete(lockKey);
|
|
|
- }
|
|
|
- return releaseLock;
|
|
|
+ return this.unlock(lockKey, null);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -89,7 +93,18 @@ public class RedisLockUtil {
|
|
|
* @return
|
|
|
*/
|
|
|
public boolean unlock(String lockKey, String lockVal) {
|
|
|
- return this.unlock(lockKey, null);
|
|
|
+ if(lockVal == null){
|
|
|
+ String threadId = String.valueOf(Thread.currentThread().getId());
|
|
|
+ lockVal = THREADID_LOCKVAL_MAP.get(threadId);
|
|
|
+ }
|
|
|
+ if (StrUtil.isEmpty(lockKey) || Objects.isNull(lockVal))
|
|
|
+ return false;
|
|
|
+ boolean releaseLock = false;
|
|
|
+ Long val = (Long) redisTemplate.opsForValue().get(lockKey);
|
|
|
+ if (lockVal.equals(val)) {
|
|
|
+ releaseLock = redisTemplate.delete(lockKey);
|
|
|
+ }
|
|
|
+ return releaseLock;
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -110,8 +125,10 @@ public class RedisLockUtil {
|
|
|
*/
|
|
|
public boolean unlockLua(String lockKey, String lockVal) {
|
|
|
if(lockVal == null){
|
|
|
- lockVal = String.valueOf(Thread.currentThread().getId());
|
|
|
+ String threadId = String.valueOf(Thread.currentThread().getId());
|
|
|
+ lockVal = THREADID_LOCKVAL_MAP.get(threadId);
|
|
|
}
|
|
|
+ log.info("解锁lockval:{}",lockVal);
|
|
|
if (StrUtil.isEmpty(lockKey) || Objects.isNull(lockVal))
|
|
|
return false;
|
|
|
DefaultRedisScript<Long> redisScript = new DefaultRedisScript();
|