I'm trying to create an infrastructure where different machines acquire shared locks through Redisson. Once the lock is acquired, some async tasks gets done, finally, when I finish the job, I'm releasing the Redisson lock through the thread currently running - but i receive the following error
java.lang.IllegalMonitorStateException: attempt to unlock lock, not locked by current thread by node id: xxxxx thread-id: 57
So, I understand the meaning of that, but since I want to perform asynchronous work, I cannot use the acquiring thread to perform the release.
Should I not use Redisson locks? What is the best match for async work like that?
As zapl mentioned, Java documentation shows that this is the proper behavior of a java lock. After discussing the issue on Reddison's GitHub page, it seems like Redisson Lock was not designed for that, and that the Redisson Semaphore will support async operations soon.
At the meantime, i plan to allocate a single thread to perform ALL locking and unlocking. Since Redisson has the support for async, non-blocking calls, this solution seems reasonable for now.
I would recommend to use Redisson Semaphore object. Since 2.2.14 version it supports asynchronous operations via RSemaphoreAsync
interface.
Since your service is running on multiple nodes. Would suggest you to use lock.isHeldByCurrentThread() method before unlocking. A sample method would like
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");
}
}
I use forceUnlock() instead of unlock(), it works and successfully release the lock locked by another thread, but may be not a recommanded way.
Another way please refer to https://github.com/redisson/redisson/issues/2224
you can use lockAsync(threadId)
and unlockAsync(threadId)
to walk around the thread id check.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With