2011-01-12 8 views
5

Si consideri il seguente codice. Per impedire listIterator durante la chiamata a listIterator, viene utilizzato un blocco lettore per recuperare l'indicatore basato su indice e il blocco scrittore su altro quando si esegue un'operazione di scrittura su stockCodes.Come useremo provare finalmente per Lock.lock e Lock.unlock

Prendere atto che, non abbiamo utilizzato alcun meccanismo di blocco per iterare utilizzando listIterator, come è da CopyOnWriteArrayList. Il blocco non è richiesto poiché ConcurrentModificationException non deve essere lanciato.

// stockCodesReaderLock is reader lock from java.util.concurrent.locks.ReadWriteLock 
// stockCodes is CopyOnWriteArrayList 
// Acquire iterator in a safe way. 
stockCodesReaderLock.lock(); 
final int stockCodesSize = stockCodes.size(); 
if (currIndex < stockCodesSize) { 
    listIterator = stockCodes.listIterator(currIndex); 
} 
stockCodesReaderLock.unlock(); 

mi chiedevo, se devo avere try/finally blocco, come non riesco a vedere alcuna possibilità di deroga a sorgere? Se si utilizza lo standard try/finally, è necessario utilizzare (A) o (B)?

C'è bisogno di me?

(A)

try { 
    stockCodesReaderLock.lock(); 
    final int stockCodesSize = stockCodes.size(); 
    if (currIndex < stockCodesSize) { 
     listIterator = stockCodes.listIterator(currIndex); 
    } 
} finally { 
    stockCodesReaderLock.unlock(); 
} 

(B)

stockCodesReaderLock.lock(); 
try { 
    final int stockCodesSize = stockCodes.size(); 
    if (currIndex < stockCodesSize) { 
     listIterator = stockCodes.listIterator(currIndex); 
    } 
} finally { 
    stockCodesReaderLock.unlock(); 
} 
+0

possibile duplicato di [Thread: Perché un blocco deve essere seguito da try e finally] (http://stackoverflow.com/questions/6950078/threads-why-a-lock-has-to-be-followed- by-try-and-finally) – Raedwald

risposta

11

Gli altri rispondenti hanno ragione: si dovrebbe sempre con utilizzare try/finally.

Per quanto riguarda se (A) o (B) è corretto, Sun sembra raccomandare (B) nello JavaDoc of ReentrantReadWriteLock (cercare "finalmente" per vederlo). Suppongo che ciò sia dovuto al fatto che il metodo lock() potrebbe generare un'eccezione se non riesce: ad esempio, JavaDoc dice che genererà un Error nel caso oscuro in cui lo stesso thread tenta di acquisire il blocco in modo ricorsivo più di 65535 volte.

+0

ok. destra. esempio di codice ufficiale da sun (oracle). non dovrebbe andare storto. –

6

E 'una buona programmazione difensiva. Se il tuo codice cambia in modo tale che il corpo generi un'eccezione per qualsiasi motivo (incluso, ad esempio, OutOfMemoryError), sarai felice di non aver lasciato il blocco in uno stato bloccato.

Personalmente andrei per (B) - se il metodo lock() stesso dovesse lanciare un'eccezione, sarebbe comunque bilanciato. Ma in pratica non penso che importi più di tanto.