redis分布式锁
package com.nio.otd.lop.inventory.util;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.StringRedisTemplate;
import java.util.concurrent.TimeUnit;
/**
* @Auther: turbo.cai
* @Date: 2019/7/25 14:42
* @Description:
*/
@Slf4j
public class MyRedisUtils {
@Autowired
StringRedisTemplate stringRedisTemplate;
/**
*
* @param lockKey
* @param lockTime 过期时间
* @return
*/
public long lock(String lockKey, Long lockTime) {
Long lockValue = System.currentTimeMillis() + lockTime;
//定义一个时间,在指定时间内可重试获取锁
Long waitTime = System.currentTimeMillis() + 1000L;
Boolean flag = stringRedisTemplate.execute((RedisCallback<Boolean>) e -> {
Boolean success = false;
try {
do {
success = e.setNX(lockKey.getBytes(), lockValue.toString().getBytes());
if (success) {
return success;
}
Thread.sleep(200);//第一次获取失败,隔200毫秒重试
} while (System.currentTimeMillis() < waitTime);//即在1000毫秒内获取锁失败还可以不断重试获取锁
} catch (Throwable ex) {
ex.printStackTrace();
}
return success;
});
if (flag) {
//加锁成功,设置过期时间
stringRedisTemplate.expire(lockKey, lockTime, TimeUnit.MILLISECONDS);
return lockValue;
}
return -1;
}
public void unlock(String lockKey,long lockValue){
//根据key获取redis存入的value
String result = stringRedisTemplate.opsForValue().get(lockKey);
Long oldValue = result == null?null:Long.valueOf(result);
if (oldValue != null && oldValue == lockValue){
stringRedisTemplate.delete(lockKey);
}else {
log.info("非加锁者,等待过期时间结束后释放锁");
}
}
}