利用setnx命令实现类似获取锁和释放锁。
获取锁,setnx lock 1,返回值为1视为获取成功,为0视为获取失败
释放锁,del lock
特殊情况:
如果获取锁之后,锁来还来不及释放,redis宕机了,这样其他线程永远无法获取锁的情况,这样就会造成死锁问题。应对这种情况,我们可以让这个锁自动过期(这里设置锁的过期时间为10s).
图1还有弊端,可能刚创建完锁还没来得及设置时间时,就宕机了
图2推荐
实现:
public class SimpleRedisLock implements ILock{
private StringRedisTemplate stringRedisTemplate;
//使用这个锁工具的业务名称
private String name;
public SimpleRedisLock(StringRedisTemplate stringRedisTemplate, String name) {
this.stringRedisTemplate = stringRedisTemplate;
this.name = name;
}
//前缀
private static final String KEY_PREFIX = "lock:";
@Override
public boolean tryLock(Long timelockSec) {
long threadid = Thread.currentThread().getId();
Boolean success = stringRedisTemplate.opsForValue().setIfAbsent(KEY_PREFIX + name, threadid + "", timelockSec, TimeUnit.SECONDS);
return Boolean.TRUE.equals(success);
}
@Override
public void unlock() {
stringRedisTemplate.delete(KEY_PREFIX + name);
}
}