@Service("RedisLockUtils")
@Slf4j
public class RedisLockUtils {
@Autowired
private RedisTemplate<String, String> redisTemplate;
public static final String LOCK_KEY="update:aaaa";
public void lock(String key) {
String lockKey = LOCK_KEY+key ;
String value = Thread.currentThread().getName();
// 使用SETNX命令尝试获取锁
/*设置锁:底层使用 Redis 命令 SETNX(SET if Not eXists)设置 Redis 锁。SETNX 这个命令用于检测一个指定key是否存在,如果key不存在,那么会设置该key,返回一个1,如果key存在那么返回一个0。*/
Boolean acquiredLock = redisTemplate.opsForValue().setIfAbsent(lockKey, value);
log.info("变更获取指定key的redis锁状态" + key+" "+lockKey+" "+acquiredLock);
if (acquiredLock != null && acquiredLock) {
// 成功获取锁,设置锁的超时时间
redisTemplate.expire(lockKey, 1, TimeUnit.MINUTES);
return;
}
throw new Exception("锁已经被获取,请稍后重试!");
}
public void unLock(String key) {
String lockKey = LOCK_KEY+key ;
String currentValue = redisTemplate.opsForValue().get(lockKey);
if (currentValue != null && currentValue.equals(Thread.currentThread().getName())) {
// 只有持有锁的线程才能释放锁
redisTemplate.delete(lockKey);
}
}
}
@Test
public void test() {
//获取锁
redisLockUtils.lock("0001");
try {
//处理业务锁
System.out.println("处理业务");
} catch (Exception e) {
log.error(e.getMessage());
} finally {
//释放锁
redisLockUtils.unLock("0001");
}
}