以下文章都是自己的理解(望各位大佬指点)
redis的分布式锁,首先redis是一个缓存的第三方工具、
其原理就是,由redis加锁也就是加一个key跟value,
解锁的时候删除那个key,当每次线程进来的时候都先去获取锁,如果获取成功就直接执行自己的业务代码,否则什么也不做,为了避免死锁的状态,加锁的时候会设置一个超时时间
/**
* redis加锁的操作
* @param key
* @param value
* @param expireTime 过期时间 毫秒
* @return
*/
public Boolean tryLock(String key, long value,long expireTime) {
if (setIfAbsent(key,value,expireTime)) {
return true;
}
Long currentValue = redisTemplate.opsForValue().get(key);
if (currentValue !=null && Long.valueOf(currentValue) < System.currentTimeMillis()) {
//获取上一个锁的时间 如果高并发的情况可能会出现已经被修改的问题 所以多一次判断保证线程的安全
Long oldValue = redisTemplate.opsForValue().getAndSet(key, value);
if (oldValue!=null && oldValue.equals(currentValue)) {
return true;
}
}
return false;
}
/**
* Redis解锁的操作
*
* @param key
* @param value
*/
public void unlock(String key, long value) {
Long currentValue = redisTemplate.opsForValue().get(key);
try {
if (currentValue!=null && currentValue.equals(value)) {
redisTemplate.opsForValue().getOperations().delete(key);
}
} catch (Exception e) {
}
}
private boolean setIfAbsent(final String key, final Serializable value, final long expireTime) {
Boolean result = (Boolean) redisTemplate.execute(new RedisCallback<Boolean>() {
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
RedisSerializer valueSerializer = redisTemplate.getValueSerializer();
RedisSerializer keySerializer = redisTemplate.getKeySerializer();
Object obj = connection.execute("set", keySerializer.serialize(key),
valueSerializer.serialize(value),
"NX".getBytes(StandardCharsets.UTF_8),
"PX".getBytes(StandardCharsets.UTF_8),
String.valueOf(expireTime).getBytes(StandardCharsets.UTF_8));
return obj != null;
}
});
return result;
}
}
以上提供两个方法一个是加锁和解锁操作