Unlock on ReentrantLock without IllegalMonitorStateException

21,137

Solution 1

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?

Solution 2

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.

Solution 3

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();
}
Share:
21,137
Mikhail
Author by

Mikhail

Updated on November 14, 2020

Comments

  • Mikhail
    Mikhail over 3 years

    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?

  • Brett
    Brett almost 14 years
    But you probably wouldn't want to.
  • john16384
    john16384 about 5 years
    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.