【问题标题】:Redisson release lock from different threadsRedisson 从不同的线程释放锁
【发布时间】:2016-09-19 09:11:26
【问题描述】:

我正在尝试创建一个基础架构,让不同的机器通过 Redisson 获取共享锁。一旦获得锁,一些异步任务就会完成,最后,当我完成工作时,我正在通过当前正在运行的线程释放 Redisson 锁 - 但我收到以下错误

java.lang.IllegalMonitorStateException: attempt to unlock lock, not locked by current thread by node id: xxxxx thread-id: 57

所以,我明白其中的意思,但是由于我要执行异步工作,我不能使用获取线程来执行释放。

我不应该使用 Redisson 锁吗?这种异步工作的最佳匹配是什么?

【问题讨论】:

  • Lock#unlock() 告诉您锁通常会这样做。因此,无论您使用什么库,都可能需要一个不同的原语,如信号量。编辑:太早按回车。
  • 谢谢! Redisson 的信号量不是异步 AFAIK,所以我不能使用它。

标签: java redis locking redisson


【解决方案1】:

正如 zapl 提到的,Java documentation 表明这是 java 锁的正确行为。 在Reddison's GitHub page 讨论了这个问题后,似乎 Redisson Lock 不是为此而设计的,而且 Redisson Semaphore 很快就会支持异步操作。

同时,我计划分配一个线程来执行所有锁定和解锁。由于 Redisson 支持异步、非阻塞调用,这个解决方案目前看来是合理的。

【讨论】:

    【解决方案2】:

    我建议使用 Redisson Semaphore 对象。从2.2.14版本开始支持通过RSemaphoreAsync接口进行异步操作。

    【讨论】:

      【解决方案3】:

      由于您的服务在多个节点上运行。建议您在解锁之前使用 lock.isHeldByCurrentThread() 方法。一个示例方法想

      RLock lock = redissonClient().getLock(lockLabel);
      try {
        if (lock.tryLock(lockAcquireWaitTime, lockLeaseTime, TimeUnit.MINUTES)) {
         //Action to be performed when lock is acquired.
          lock.unlock();
        }
        Thread.sleep(syncMonitorInterval);
      } catch (Exception e) {
        LOG.error("Error..", e);
      } finally {
        if (lock != null && lock.isLocked() && lock.isHeldByCurrentThread()) {
          lock.unlock();
          LOG.debug("lock released");
        }
      }
      

      【讨论】:

        【解决方案4】:

        我使用 forceUnlock() 而不是 unlock(),它可以工作并成功释放被另一个线程锁定的锁,但可能不是推荐的方式。

        其他方式请参考https://github.com/redisson/redisson/issues/2224 您可以使用lockAsync(threadId)unlockAsync(threadId) 来遍历线程ID 检查。

        【讨论】:

          猜你喜欢
          • 2018-11-13
          • 2014-12-01
          • 1970-01-01
          • 1970-01-01
          • 2016-03-05
          • 1970-01-01
          • 1970-01-01
          • 2016-01-23
          • 1970-01-01
          相关资源
          最近更新 更多