RedisTemplate实现分布式锁
@Autowired
private StringRedisTemplate redisTemplate;
int timeOut = 10; //过期时间
String lockKey = "redis键";
String redisClientID = UUID.randomUUID().toString(); //作为value传入,用于保证是当前线程释放锁
public String test() {
//设置锁,timeOut,TimeUnit.SECONDS 为过期时间参数
boolean f = redisTemplate.opsForValue().setIfAbsent(lockKey, redisClientID, timeOut, TimeUnit.SECONDS);
if (!f) {
return "当前操作数过多,请稍后重试";
}
//开启守护线程,作用:防止业务还没有执行完但是时间到期了
new GuardThread(lockKey, timeOut, redisTemplate).start();
try {
//执行业务逻辑
} finally {
//释放锁
if (redisTemplate.opsForValue().get(lockKey).equals(redisClientID)) {
//保证当前线程释放
redisTemplate.delete(lockKey);
}
}
return "";
}
守护线程:
逻辑:延长过期时间
public class GuardThread extends Thread{
private String lockKey;
private int timeOut;
private StringRedisTemplate redisTemplate;
public GuardThread(String lockKey,int timeOut,StringRedisTemplate redisTemplate){
this.lockKey=lockKey;
this.timeOut=timeOut;
this.redisTemplate=redisTemplate;
}
@Override
public void run() {
while (true){
try {
Thread.sleep(timeOut/2*1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Long expire = redisTemplate.getExpire(lockKey, TimeUnit.SECONDS);
if (expire>0){
redisTemplate.expire(lockKey,expire+timeOut/2,TimeUnit.SECONDS);
}
}
}
}