2015-10-11 18 views
7

Ho letto in alcuni punti che non è buona pratica di programmazione acquisire un oggetto Lock senza che il codice sia racchiuso in un blocco try...finally in modo che il blocco possa essere rilasciato anche se viene generata un'eccezione.Un thread rilascia un lucchetto quando termina?

Potrebbe sembrare una semplice domanda: tutti i blocchi di un thread vengono rilasciati automaticamente al termine del thread?

Il motivo per cui faccio questa domanda è che il programma su cui sto lavorando è tale che una volta che un thread acquisisce un blocco, non dovrebbe avere alcun motivo lasciarlo andare fino a quando non termina. Inoltre, sono nuovo nell'usare i lucchetti, quindi mi chiedo se non ci siano insidie ​​che forse non ho considerato. Devo preoccuparmi di rilasciare esplicitamente dei blocchi nel mio codice prima che il thread finisca, o posso lasciarlo alla JVM, fiducioso nella certezza che gli altri thread bloccati su tutti i blocchi del thread attivo saranno attivati ​​non appena il il filo si arresta?

+0

Si prega di inviare un po 'di codice. – C1sc0

+0

@ C1sc0: qualche codice su cosa? La domanda ha una dichiarazione del problema abbastanza chiara. – Patrick

+0

Probabilmente è possibile testarlo con un'applicazione molto semplice. Crea due thread, prova ad acquisire lo stesso lock e uccidi il thread subito dopo. Se il secondo thread ottiene il blocco, è effettivamente sbloccato. – Patrick

risposta

3

prova semplice può mostrare che il blocco non viene rilasciato al momento della cessazione discussione:

import java.util.concurrent.locks.Lock; 
import java.util.concurrent.locks.LockSupport; 
import java.util.concurrent.locks.ReentrantLock; 

public class LockTest { 
    public static void main(String[] args) { 
     final Lock l = new ReentrantLock(); 

     Thread t = new Thread() { 
      @Override 
      public void run() { 
       System.out.println(Thread.currentThread()+": Acquire lock"); 
       l.lock(); 
       System.out.println(Thread.currentThread()+": Lock aquired: wait"); 
       LockSupport.parkNanos(1_000_000_000); 
       System.out.println(Thread.currentThread()+"; Exiting"); 
      } 
     }; 
     t.start(); 
     LockSupport.parkNanos(500_000_000); 
     System.out.println(Thread.currentThread()+": Acquire lock"); 
     l.lock(); 
     System.out.println(Thread.currentThread()+"; Success!"); 
    } 
} 

uscita:

Thread[Thread-0,5,main]: Acquire lock 
Thread[Thread-0,5,main]: Lock aquired: wait 
Thread[main,5,main]: Acquire lock 
Thread[Thread-0,5,main]; Exiting 
// "Success" is never written: stuck in dead-lock 

Così, quando il thread separato acquisito la serratura, poi esce, blocco non può essere presa per filo principale

+0

Sarebbe bello i blocchi associati che sono stati acquisiti da un particolare thread con quel thread - l'API (in qualche modo sorprendentemente) non sembra farlo. Suppongo che possa contenere una collezione di blocchi acquisiti in un'implementazione personalizzata del thread e rilasciarli tutti prima della fine del thread. Non so se questo ha delle insidie ​​... –

+0

@OwenThomas, API associa il lucchetto al thread. Puoi verificarlo cercando di sbloccare il blocco acquisito da un altro thread: otterrai un'eccezione. L'aggiunta dello sblocco automatico dopo il termine del thread è troppo lavoro non necessario e sovraccarico non necessario. –

+0

Esiste un metodo per chiamare il thread corrente, qualcosa come getLocks(), che restituisce una raccolta contenente i blocchi dei thread? –

Problemi correlati