摘要:一个实现分布式锁的方案,它使用了Redis的【set key_lock value NX PX 失效时间】命令,NX表示只有在key_lock不存在时才能set成功,PX表示设置key_lock的失效时间
在前面的文章《Redis实现分布式锁方案一(Java源码)》已经提出了一个用redis实现分布式锁的完整方案,但方案对于客户端时间不一致造成的问题还无法解决,所以我们应该考虑是否还有其它的方案可以实现分布式锁呢?

在Redis的官方网站上分享了一个实现分布式锁的方案,它使用了Redis的【set key_lock value NX PX 失效时间】命令,NX表示只有在key_lock不存在时才能set成功,PX表示设置key_lock的失效时间,详细的方案流程如下:
1、请求锁时,调用【set key_lock value NX PX 失效时间】命令,
          返回1说明获取锁成功;
          返回0说明获取锁失败,等待或者重新请求获取;
2、执行任务,完成后调用【del key_lock】释放锁;

整个流程非常简单,但是要注意的是客户端每次请求锁时set进去的value最好都是唯一的,可以考虑使用一个随机数,这样才能保证安全的释放锁。

Java实现获取锁的代码:
public synchronized boolean lock(Jedis jedis){
    int retryTime = RETRY_TIME;
    try {
        while (retryTime > 0) {
            lockValue = System.nanoTime();
            if ("OK".equalsIgnoreCase(jedis.set(LOCK_KEY,
                String.valueOf(lockValue), "NX", "PX", EXPIRE_TIME))) {
                locked = true;
                return locked;
            }
            retryTime -= 100;
            Thread.sleep(100);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return false;
}

Java实现释放锁的代码:
public synchronized void unlock(Jedis jedis){
    if(locked) {
        String currLockVal = jedis.get(LOCK_KEY);
        if(currLockVal!=null && Long.valueOf(currLockVal)
            == lockValue){
            jedis.del(LOCK_KEY);
            locked = false;
        }
    }
}

这种方案能够很好的解决死锁问题,也不用担心各客户端时间不同步的问题,因为锁的超时是通过Redis本身的失效机制保证的。但是,对于锁的意义来说,这种方案不能体现锁在用加锁,不用时释放的特点。总的来说我还是比较倾向于使用这种方案,因为它的用法比较简单,而且不用担心客户端时间戳不同步带来的问题。


源码已经提交在GitHub:https://github.com/beyondfengyu/DistributedLock (JedLock.java)


参考文章

版权说明:如无特殊说明,文章均为本站原创,如需转载请注明出处

本文标题:Redis实现分布式锁方案二(Java源码)

本文地址:http://www.wolfbe.com/detail/201612/385.html

本文标签: 分布式锁 redis java

感谢您的支持,朗度云将继续前行

扫码打赏,金额随意

温馨提醒:打赏一旦完成,金额无法退还,请谨慎操作!

扫二维码 我要反馈 回到顶部