在没有IllegalMonitorStateException的情况下解锁ReentrantLock

Mik*_*ail 11 java concurrency locking

我有一段代码(简化):

if(reentrantLockObject.isLocked()) {
       reentrantLockObject.unlock();
}
Run Code Online (Sandbox Code Playgroud)

其中reentrantLockObject是java.util.concurrent.locks.ReentrantLock.有时我得到IllegalMonitorStateException.它接缝在check和unlock()调用之间释放了锁.如何防止此异常?

Jon*_*eet 20

isLocked返回任何线程是否持有锁.我想你想要isHeldByCurrentThread:

if (reentrantLockObject.isHeldByCurrentThread()) {
    reentrantLockObject.unlock();
}
Run Code Online (Sandbox Code Playgroud)

据说,isHeldByCurrentThread记录主要用于诊断目的 - 这段代码是正确的方法是不寻常的.你能解释为什么你认为你需要它吗?


Joh*_*int 6

你需要拥有锁才能解锁它.reentrantLockObject.isLocked()仅在某些线程拥有锁时才为true,不一定是你.

  reentrantLockObject.lock();
  try{

       // do stuff
  }finally{
         reentrantLockObject.unlock();
  }
Run Code Online (Sandbox Code Playgroud)

这里线程拥有锁,因此他们可以解锁它.


Dav*_*ili 6

ReentrantLock 根据这个逻辑抛出这个异常:

if (Thread.currentThread() != getExclusiveOwnerThread()) {
  throw new IllegalMonitorStateException();
}
Run Code Online (Sandbox Code Playgroud)

所以解决方案是检查是否是同一个线程正在解锁:

if (reentrantLockObject.isHeldByCurrentThread()) {
  reentrantLockObject.unlock();
}
Run Code Online (Sandbox Code Playgroud)