Разблокировка с помощью ReentrantLock без исключения IllegalMonitorStateException - PullRequest
11 голосов
/ 11 мая 2010

У меня есть кусок кода (упрощенно):

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

где reentrantLockObject - это java.util.concurrent.locks.ReentrantLock. Иногда я получаю IllegalMonitorStateException. Он показывает, что блокировка была снята между вызовами check и unlock (). Как я могу предотвратить это исключение?

Ответы [ 3 ]

20 голосов
/ 11 мая 2010

isLocked возвращает, удерживает ли какой-либо поток блокировку.Я думаю, что вы хотите isHeldByCurrentThread:

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

Сказав, что isHeldByCurrentThread задокументировано в основном для диагностических целей - было бы необычно, если бы этот фрагмент кода был правильным подходом.Можете ли вы объяснить, почему вы думаете, что вам это нужно?

6 голосов
/ 11 мая 2010

Вам нужно владеть замком, чтобы иметь возможность его разблокировать. reentrantLockObject.isLocked () имеет значение true, только если какой-то поток владеет блокировкой, не обязательно вами.

  reentrantLockObject.lock();
  try{

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

Здесь поток владеет блокировкой, чтобы иметь возможность разблокировать ее.

3 голосов
/ 05 марта 2015

ReentrantLock выдает это исключение в соответствии с этой логикой:

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

Таким образом, решение состоит в том, чтобы проверить, разблокируется ли тот же поток:

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