7

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

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

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

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

4

4 回答 4

5

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

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

于 2016-05-22T14:20:45.497 回答
1

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

于 2016-06-04T08:09:33.990 回答
1

由于您的服务在多个节点上运行。建议您在解锁之前使用 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");
  }
}
于 2020-06-25T03:05:13.600 回答
0

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

另一种方法请参考https://github.com/redisson/redisson/issues/2224 您可以使用lockAsync(threadId)unlockAsync(threadId)绕过线程 id 检查。

于 2021-06-22T03:09:08.953 回答