概念这里就不说了直接提供方法 redisUtil中setNx方法可以实现分布式锁 /** * @param key * @param value * @param timeout 过期时间(单位秒) * @return */ public boolean setNx(String key, Object value, long timeout) { try { if(Objects.isNull(value)){ return false; } return redisTemplate.opsForValue().setIfAbsent(key, value, timeout, TimeUnit.SECONDS); } catch (Exception e) { e.printStackTrace(); return false; } }
自定义redisLock工具类
public RedisLock(String redisLockKey) { this.redisLockKey = redisLockKey; } /** * 基于redis实现获取锁与释放锁 * * @param acquireTimeOut 获取锁之前的超时时间 毫秒 * @param expire 获取锁之后的超时时间 毫秒 * @return */ public String getRedisLock(RedisUtil redisUtil, Long acquireTimeOut, Long expire) { //1.建立连接 //conn = jedisPool.getResource(); //2.定义redis 对应的 key 和 value value作用:释放锁。随机生成value String randomValue = UUID.randomUUID().toString(); //3.定义获取锁之后的超时时间,转化为以秒为单位 int expireLock = (int) (expire / 1000); //4.定义在获取锁之前的超时时间 //5.使用循环机制 如果没有获取到锁,要在规定的 acquireTimeOut 时间 保证重复的获取锁 //long endTime = System.currentTimeMillis() + 10; //6.使用setNx命令插入对应 key,如果返回1则表示创建成功 if (redisUtil.setNx(redisLockKey, randomValue, expireLock)) { //设置 key 对应的有效期,防止死锁 // redisUtil.expire(redisLockKey, expireLock); return randomValue; } return null; } /** * 释放锁 * 释放锁有2种方式 * 1:key 设置有效期,自动删除 * 2:整个程序执行完毕情况下,删除对应的key * 如果直接使用 conn.del(redisLockKey);无法保证是自己创建的锁,可能会产生误删除 * 所以需要保证删除的锁是自己创建的 redisLockKey,根据 randomValue 。 * * @param randomValue 作用:释放属于自己锁 */ public void unRedisLock(RedisUtil redisUtil, String randomValue) { //删除自己对应的锁 // if (redisUtil.get(redisLockKey).equals(randomValue)) { // //System.out.println("释放锁" + Thread.currentThread().getName() + ",randomValue:" + randomValue); // //删除 // redisUtil.del(redisLockKey); // } if (randomValue.equals(redisUtil.get(redisLockKey))) { //System.out.println("释放锁" + Thread.currentThread().getName() + ",randomValue:" + randomValue); //删除 redisUtil.del(redisLockKey); } else { log.warn("分布式锁失效,key={}", redisLockKey); } }