Redis实现分布式锁
一.主要用到的函数
1.setNX(key, value): 如果key不存在的设置value值,否则就不设置,设置成功则返回1,设置失败则返回0。
2.getSet:获得设置之前的值并给其设置新的值。
二.redis锁实现原理
1.在第一个线程进来的时候调用setNX方法设置名称和对应的时间戳加过期时间
jedis.setNX("redisKey", System.currentTimeMillis() + expireTime)
2.在第二个线程进来的时候调用setNX方法时如果返回1则说明上一个线程已经执行完成了,redis锁已经被释放了,如果返回0则说明锁没有被释放,则可以等待或者重试
3.具体代码实现(这里面有个防止线程饥饿的判断,没弄懂啥意思)
//加锁的代码实现
public synchronized boolean lock() {
int timeout = this.timeout;
long expires = System.currentTimeMillis() + expire + 1;
String expiresStr = String.valueOf(expires) + ";" + hostName;
//如果设置成功了则返回1
if(jedis.setNX(lockKey, expiresStr) == 1){
return true;
}else {
//从redis中获得过期时间
String oldValue = jedis.get(lockKey);
if(oldValue < System.currentMillis){
//说明已经过期了,可以获得锁
String currentTime = jedis.getSet(lockKey,
System.currentTimeMillis() + expire + 1);
//由于getSet()是同步的所以返回的值一定是最新的一个
//比较currentTime和oldValue的值,如果不相同的话说明此时被其他的线程改篡改了
if(currentTime.equals(oldValue)){
//说明没有被篡改,此时的锁已经过期了
return true;
}else {
return false;
}
}else {
//没有过期
return false;
}
}
}
//释放锁的代码实现
public sychronized boolean unlock() {
jedis.delete(lockKey);
}
详细实现代码:https://www.cnblogs.com/SimplifyIT/p/6691584.html