12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091 |
- package com.fdkankan.redis.util;
- import cn.hutool.core.util.StrUtil;
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.data.redis.core.RedisTemplate;
- import org.springframework.data.redis.core.script.DefaultRedisScript;
- import org.springframework.stereotype.Component;
- import java.util.Arrays;
- import java.util.Objects;
- import java.util.concurrent.TimeUnit;
- @Component
- @Slf4j
- public class RedisLockUtil {
- @Autowired
- private RedisTemplate redisTemplate;
- private static final String UNLOCK_LUA =
- "if redis.call('get',KEYS[1]) == ARGV[1] then\n" +
- " return redis.call('del',KEYS[1])\n" +
- "else\n" +
- " return 0\n" +
- "end";
- /**
- * 加锁,自旋重试三次
- *
- * @param lockKey 锁key
- * @param expireTime 锁过期时间 单位 毫秒
- * @return
- */
- public boolean lock(String lockKey, int expireTime) {
- boolean locked = false;
- int tryCount = 3;
- String threadId = String.valueOf(Thread.currentThread().getId());
- while (!locked && tryCount > 0) {
- locked = redisTemplate.opsForValue().setIfAbsent(lockKey, threadId, expireTime, TimeUnit.SECONDS);
- tryCount--;
- try {
- Thread.sleep(300);
- } catch (InterruptedException e) {
- log.error("线程被中断[线程id:" + threadId + "]", e);
- }
- }
- return locked;
- }
- /**
- * 非原子解锁,可能解别人锁,不安全
- *
- * @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;
- }
- /**
- * 使用lua脚本解锁,不会解除别人锁
- *
- * @param
- * @return
- */
- public boolean unlockLua(String lockKey) {
- String threadId = String.valueOf(Thread.currentThread().getId());
- if (StrUtil.isEmpty(lockKey) || Objects.isNull(threadId))
- 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);
- return result.equals(Long.valueOf(1));
- }
- }
|