2010-05-11 8 views
9

tengo una pieza de código (simplificado):de desbloqueo de ReentrantLock sin IllegalMonitorStateException

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

donde reentrantLockObject es java.util.concurrent.locks.ReentrantLock. A veces recibo IllegalMonitorStateException. Se ve que el bloqueo se liberó entre la llamada de verificación y la de desbloqueo(). ¿Cómo puedo evitar esta excepción?

+0

@Mihail, si usted no sabe si no su hilo mantiene el candado, le sugiero que podría estar haciendo algo mal. –

Respuesta

15

isLocked devuelve si cualquier hilo mantiene el bloqueo. Creo que quieres isHeldByCurrentThread:

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

Dicho esto, isHeldByCurrentThread se documenta ser principalmente para fines de diagnóstico - que sería inusual para este trozo de código que es el enfoque correcto. ¿Puedes explicar por qué crees que lo necesitas?

+0

Pero probablemente no quieras. –

+0

@Tom: Es cierto: generalmente no es una buena idea. Editaré –

6

Necesita tener el candado para poder desbloquearlo. reentrantLockObject.isLocked() solo es verdadero si algún hilo posee el bloqueo, no necesariamente usted.

reentrantLockObject.lock(); 
    try{ 

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

Aquí el hilo posee la cerradura para que puedan desbloquearlo.

3

ReentrantLock lanza esta excepción según esta lógica:

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

Así que la solución es comprobar si el mismo hilo es desbloquear:

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