2010-05-11 16 views
9

Ho un pezzo di codice (semplificato):Sblocca ReentrantLock senza IllegalMonitorStateException

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

dove reentrantLockObject è java.util.concurrent.locks.ReentrantLock. A volte ricevo IllegalMonitorStateException. È stato rilasciato il blocco tra la chiamata di controllo e quella di sblocco(). Come posso evitare questa eccezione?

+0

@Mihail, se non si sa se o non il tuo thread tiene il lucchetto, ti suggerirei che potresti fare qualcosa di sbagliato. –

risposta

15

isLocked restituisce se qualsiasi thread mantiene il blocco. Penso che si desidera isHeldByCurrentThread:

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

Detto questo, isHeldByCurrentThread è documentato essere principalmente per scopi diagnostici - sarebbe insolito per questo pezzo di codice per essere il giusto approccio. Puoi spiegare perché pensi di averne bisogno?

+0

Ma probabilmente non lo vorrai. –

+0

@Tom: True: non è generalmente una buona idea. Modificherà. –

6

È necessario possedere il blocco per poterlo sbloccare. reentrantLockObject.isLocked() è true solo se alcuni thread possiedono il lock, non necessariamente te.

reentrantLockObject.lock(); 
    try{ 

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

Qui il thread possiede il blocco in modo che siano in grado di sbloccarlo.

3

ReentrantLock genera questa eccezione secondo questa logica:

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

Quindi la soluzione è quella di verificare se lo stesso filo viene sblocco:

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