【问题标题】:Redis's Redisson's API method .unlock() is not releasing the lock, trying from the same instanceRedis 的 Redisson 的 API 方法 .unlock() 没有释放锁,尝试从同一个实例
【发布时间】:2020-09-11 10:24:39
【问题描述】:

我在我的 Java 应用程序中创建了单例 redisson 实例,我用它来与 redis 服务器通信。 现在使用这个 redisson 实例,我正在获取一个锁,在完成一些任务后,我正在释放它。但是调用unlock方法后,我仍然看到redis有锁,其他线程无法获取锁。 下面是我正在使用的代码sn-p:

class RedisInstance
{
   static RedisInstance ins;
   private RedisInstance()
     {
       ins = new RedisInstance();
     }
   public static RedisInstance getInstance()
     {
       return ins;
     }
   //Acquire the lock:   
   public boolean acquireLock(String lockKey)
     {
         RLock redisLock = getRedisClient().getLock(lockKey);
         boolean isLockFree;
         try 
         {
            isLockFree = redisLock.tryLock(lockAcquistionTimeLimit, TimeUnit.SECONDS);
            if(isLockFree)
            {
                 redisLock.lock();
                 logger.info("lock acquired for: {}", lockKey);
                 return true;
            }
         } 
         catch (InterruptedException e) 
         {
             logger.error("Got exception {} in acquiring Redis Lock for: {}" , e, lockKey);
         }
         
         return false;
     }


   //Release the lock:
   public void unlock(String lockKey)
     {
         RLock redisLock = getRedisClient().getLock(lockKey);
         redisLock.unlock();
         logger.debug("IS redis locked "+redisLock.isLocked());
         logger.info("lock released for: {}", lockKey);
     }
}
class A
{
   RedisIns ins = RedisInstance.getInstance();
   public void run() 
        {
        if(ins.acquireLock(lockKey))
                {
                    try 
                    {
                        //do some processing takes less than a second       
                    }
                    catch(Exception e)
                    {
                        
                    }
                    finally
                    {
                        ins.unlock(lockKey);
                    }
                }
         }
   //In my main method:
   public static void main(String args[])
   {
     A a = new A();
     A b = new A();
     Thread t1 = new Thread(a);
     Thread t2 = new Thread(b);
     t1.start();
     Thread.sleep(5000); //just to mock, lets say t1 finishes before t2 starts
     t2.start();
   }
}

t1 调用ins.unlock(lockKey); 后,日志logger.debug("IS redis locked "+redisLock.isLocked()); 显示:true 并且t2 无法获取锁。

但是,如果我将 redisLock.unlock(); 替换为 redisLock.forceUnlock();,一切都会按预期工作。 不知道为什么 unlock() 无法释放锁 forceUnlock() 能够做到。

【问题讨论】:

    标签: java redis


    【解决方案1】:

    如果获得锁,tryLock 返回真。所以调用 lock after 是不必要的,我认为这可能是你的问题的原因。该实现可能需要偶数个锁定/解锁,并且在您的情况下,您的锁定比解锁多一个。

    【讨论】:

    • 感谢您的指出,我删除了额外的 lock() 并且它现在正在工作,但是对于 Redis 为什么它会这样做,它不应该只有一个锁,而且这个是一个锁而不是一个信号量,它跟踪调用的 lock() 和 unlock() 的数量。
    • 从文档中它说它实现了一个远程java并发锁。我认为锁计数是为了允许重入锁,如果锁/解锁不平衡,它将不允许获取锁的方法调用另一个获取相同锁并解锁它的方法,因为它会从第一个方法释放锁在退出受保护的块之前。
    猜你喜欢
    • 2016-09-19
    • 1970-01-01
    • 2021-04-05
    • 2020-06-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-03
    • 2018-09-17
    • 2021-05-04
    相关资源
    最近更新 更多