1 基础方法
/**
* 如果为空就插入值,返回true,如果不为空则不做操作,返回false
* @param key
* @param value
* @return
*/
public static Boolean setIfAbsent(String key, String value){
return redisTemplate.opsForValue().setIfAbsent(key, value);
}
/**
* 插入新值并返回旧值
* @param key
* @param value
* @return
*/
public static String getAndSet(String key, String value){
return redisTemplate.opsForValue().getAndSet(key, value);
}
2 流程图

3 代码
/**
* 获取分布式锁,获取不成功会一直尝试获取
* @param redisKey
* @return
*/
public static boolean getDistributedLock(StrRedisKey redisKey){
try {
String currentMill= DateUtil.current(false) + "";
while (true){
Boolean getLock =RedisClientUtil.setIfAbsent(redisKey.getDataBaseKey(), currentMill);
if(getLock){
logger.debug(Thread.currentThread().getName() + "-成功获取分布式锁【"+ redisKey.getDataBaseKey() +"】");
return true;
}else {
logger.debug(Thread.currentThread().getName() + "-获取分布式锁【"+ redisKey.getDataBaseKey() +"】失败,将尝试重新获取锁");
while (true){
String currentLockValue = RedisClientUtil.get(redisKey);
long currentLockTime,oldLockTime;
if(StrUtil.isNotBlank(currentLockValue)){
currentLockTime = Long.parseLong(currentLockValue);
if(DateUtil.current(false) - currentLockTime > ConfigUtil.getDistributeLockTimeOutValue()){
logger.debug(Thread.currentThread().getName() + "-当前的分布式锁【"+ redisKey.getDataBaseKey() +"】已经超时,将尝试强制获取锁");
String oldLockValue = RedisClientUtil.getAndSet(redisKey.getDataBaseKey(), DateUtil.current(false) + "");
if(StrUtil.isNotBlank(oldLockValue)){
oldLockTime = Long.parseLong(oldLockValue);
if(currentLockTime == oldLockTime){
logger.debug(Thread.currentThread().getName() + "-成功获取分布式锁【"+ redisKey.getDataBaseKey() +"】");
return true;
}else {
logger.debug(Thread.currentThread().getName() + "-已经有其他客户端抢先获取到分布式锁【"+ redisKey.getDataBaseKey() +"】,将稍后重试获取锁");
try {
Thread.sleep(50);
} catch (InterruptedException e) {
logger.warn(e.getMessage(),e);
}
}
}else {
logger.debug(Thread.currentThread().getName() + "-当前分布式锁【"+ redisKey.getDataBaseKey() +"】已经被释放,将尝试重新获取锁");
break;
}
}else {
logger.debug(Thread.currentThread().getName() + "-分布式锁【"+ redisKey.getDataBaseKey() +"】正在被其他客户端使用,将稍后重试获取锁");
try {
Thread.sleep(50);
} catch (InterruptedException e) {
logger.warn(e.getMessage(),e);
}
}
}else {
logger.debug(Thread.currentThread().getName() + "-当前分布式锁【"+ redisKey.getDataBaseKey() +"】已经被释放,将尝试重新获取锁");
break;
}
}
}
}
}catch (Exception ex){
logger.error(ex.getMessage(),ex);
return true;
}
}
/**
* 尝试获取分布式锁,获取失败则直接返回
* @param redisKey
* @return
*/
public static boolean tryGetDistributedLock(StrRedisKey redisKey){
String currentMill= DateUtil.current(false) + "";
Boolean getLock =RedisClientUtil.setIfAbsent(redisKey.getDataBaseKey(), currentMill);
if(getLock){
logger.debug(Thread.currentThread().getName() + "-成功获取分布式锁【"+ redisKey.getDataBaseKey() +"】");
return true;
}
logger.debug(Thread.currentThread().getName() + "-尝试获取分布式锁【"+ redisKey.getDataBaseKey() +"】失败");
return false;
}
/**
* 释放分布式锁
* 可能会出现释放不成功的情况,不需处理,只需等待自动超时即可
* @param redisKey
* @return
*/
public static boolean releaseDistributedLock(StrRedisKey redisKey){
RedisClientUtil.delete(redisKey);
logger.debug(Thread.currentThread().getName() + "-成功释放分布式锁【"+ redisKey.getDataBaseKey() +"】");
return true;
}