Unlock on ReentrantLock without IllegalMonitorStateException
Asked Answered
P

4

15

I have a piece of code (simplified):

if(reentrantLockObject.isLocked()) {
       reentrantLockObject.unlock();
}

where reentrantLockObject is java.util.concurrent.locks.ReentrantLock. Sometimes I get IllegalMonitorStateException. It seams that lock was released between check and unlock() call. How can I prevent this exception?

Paramedical answered 11/5, 2010 at 13:51 Comment(1)
@Mihail, If you don't know whether or not your thread holds the lock, I'd suggest you might be doing something wrong.Sternlight
O
25

isLocked returns whether any thread holds the lock. I think you want isHeldByCurrentThread:

if (reentrantLockObject.isHeldByCurrentThread()) {
    reentrantLockObject.unlock();
}

Having said that, isHeldByCurrentThread is documented to be mainly for diagnostic purposes - it would be unusual for this piece of code to be the right approach. Can you explain why you think you need it?

Otero answered 11/5, 2010 at 13:54 Comment(2)
But you probably wouldn't want to.Banquet
Even though the docs may state that it is typically used for debugging and testing (although it also states it can be used to ensure the lock is used in a non-reentrant manner), its function is still well documented, and as such you should be able to rely on it. I think it is definitely a cleaner solution for cases where you need to unlock halfway a block of code (that calculated half a dozen variables declared inside it), but still want the safety of a finally block if an exception occured before the unlock was reached.Musgrove
T
8

ReentrantLock throws this exception according to this logic:

if (Thread.currentThread() != getExclusiveOwnerThread()) {
  throw new IllegalMonitorStateException();
}

So the solution is to check if the same thread is unlocking:

if (reentrantLockObject.isHeldByCurrentThread()) {
  reentrantLockObject.unlock();
}
Tollmann answered 5/3, 2015 at 12:37 Comment(0)
P
7

You need to own the lock to be able to unlock it. reentrantLockObject.isLocked() only is true if some thread owns the lock, not necessarily you.

  reentrantLockObject.lock();
  try{

       // do stuff
  }finally{
         reentrantLockObject.unlock();
  }

Here the thread owns the lock so they are able to unlock it.

Pleo answered 11/5, 2010 at 13:56 Comment(0)
M
1
 private ReentrantLock lock = new ReentrantLock();
if (lock.tryLock()) {
       try {
              //your code
       } finally {
              lock.unlock();
       }
 }
Mastin answered 4/12, 2022 at 17:11 Comment(1)
Please don't post only code as answer, but also provide an explanation what your code does and how it solves the problem of the question. Answers with an explanation are usually more helpful and of better quality, and are more likely to attract upvotes.Ashok

© 2022 - 2024 — McMap. All rights reserved.