@Autowired
private RedisTemplate<String, String> redisTemplate;
//有死锁问题,设置锁的过期时间防止死锁
public void incr() {
Boolean lock = redisTemplate.opsForValue().setIfAbsent("lock", "1111"); //setnx,只有key不存在才能设置成功
if (lock) {
String num = redisTemplate.opsForValue().get("num");
Integer intNum = Integer.valueOf(num);
intNum = intNum + 1;
redisTemplate.opsForValue().set("num",intNum.toString());
redisTemplate.delete("lock");
}else {
incr();
}
public void incr() {
//设置过期时间后出现了锁不住、删除别人锁的问题
//保证加锁和设置锁时间原子性
Boolean lock = redisTemplate.opsForValue().setIfAbsent("lock", "1111",30, TimeUnit.SECONDS);
if (lock) {
String num = redisTemplate.opsForValue().get("num");
Integer intNum = Integer.valueOf(num);
intNum = intNum + 1;
redisTemplate.opsForValue().set("num",intNum.toString());
redisTemplate.delete("lock");
}else {
incr();
}
public void incr() {
//给当前线程设置一个标识,在删除锁的时候,判断一下这把锁是否是自己的,锁不住问题没有解决
String uuid = UUID.randomUUID().toString();
//保证加锁和设置锁时间原子性
Boolean lock = redisTemplate.opsForValue().setIfAbsent("lock", uuid, 30, TimeUnit.SECONDS);
if (lock) {
String num = redisTemplate.opsForValue().get("num");
Integer intNum = Integer.valueOf(num);
intNum = intNum + 1;
redisTemplate.opsForValue().set("num", intNum.toString());
//使用lua表达式确保拿比删操作的原子性
String luaString = "if redis.call('get',KEYS[1]) == ARGV[1] " +
"then " +
"return redis.call('del',KEYS[1]) " +
"else " +
" return 0 " +
"end";
redisTemplate.execute(new DefaultRedisScript<Long>(luaString, Long.class), Arrays.asList("lock"), uuid);
/* String redisUuid = redisTemplate.opsForValue().get("lock");
if(uuid.equals(redisUuid)){
redisTemplate.delete("lock");
}*/
} else {
incr();
}
}
使用Redission解决锁不住的问题
如果没有添加过期时间,默认锁时间是30s,且每到20s,会再次续期成30s,直到释放锁,或者是出现宕机 ,出现异常, 为止
分布式锁面试回答思路
1、介绍单体锁
2、引入分布式锁 手写分布式锁 遇见的问题 解决这些问题
3、我们工作中使用的是redisson,引出看门狗这个名词,总结源码
4、我们在项目中如何使用
Redission源码
标签:intNum,String,实现,lock,opsForValue,redis,num,redisTemplate,分布式 From: https://www.cnblogs.com/DuX1ao/p/17507440.html1、抢锁的时候,以看门狗时间作为锁失效时间,每隔 30s (看门狗时间)/3 = 10s 再续约成30s
2、如果你设置了时间,就以你设置的时间作为锁失效时间,还不会续期