Fork me on GitHub

redis做分布式锁的实现

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