package com.zbkj.common.utils; import lombok.SneakyThrows; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.util.concurrent.*; /** * redis分布式锁 * @author ZXF * @create 2023/05/10 0010 15:06 * @version * @注意事项 */ @Component public class RedisLockUtil { private static final ConcurrentHashMap futureMap = new ConcurrentHashMap<>(); //锁过期时间 protected long internalLockLeaseTime = 10L; //监听锁过期时间 protected long lockListenTime = internalLockLeaseTime + 1L; ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(4); @Autowired private RedisUtil redisUtil; //锁键 private String lock_value = "pasp_lock_value"; //获取锁的超时时间 private long timeout = 5L; /** * 开启定时刷新 */ protected void scheduleExpirationRenewal(String key) { ScheduledFuture future = executorService.schedule(new ExpirationRenewal(key), lockListenTime, TimeUnit.SECONDS); futureMap.put(key, future); } /** * 加锁 * * @param id * @return */ public boolean lock(String id) { Long start = System.currentTimeMillis(); for (; ; ) { //SET命令返回OK ,则证明获取锁成功 boolean lock = redisUtil.setNx(id, lock_value, internalLockLeaseTime); if (lock) { scheduleExpirationRenewal(id); //开启延迟线程,判断10s后是否释放锁,没释放则继续持有锁 return lock; } //否则循环等待,在timeout时间内仍未获取到锁,则获取失败 long l = System.currentTimeMillis() - start; if (l >= timeout) { return false; } try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } } /** * 解锁 * * @param id * @return */ public void unlock(String id) { //如果提前释放锁,就删除定时任务 redisUtil.delete(id); ScheduledFuture future = futureMap.get(id); if (future != null) { future.cancel(false); } } public RedisUtil getRedisUtil() { return redisUtil; } /** * 刷新key的过期时间 */ private class ExpirationRenewal implements Runnable { private String key; public ExpirationRenewal(String key) { this.key = key; } @SneakyThrows @Override public void run() { if (redisUtil.exists(key)) { System.out.println("执行延迟失效时间中..."); redisUtil.expire(key, internalLockLeaseTime); } } } }