首页 > 解决方案 > Redis 的 Redisson 的 API 方法 .unlock() 没有释放锁,尝试从同一个实例

问题描述

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

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() 能够做到。

标签: javaredis

解决方案


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


推荐阅读