2013-07-16 20 views
23

Ho cercato di capire le serrature e i semafori del rientro (il nidificazione delle serrature reentrate rispetto al meccanismo di sblocco/sblocco).Semaforo binario rispetto a ReentrantLock

Sembra che avere un semaforo richieda di scrivere un'applicazione più accuratamente testata perché il metodo release() non controlla se il thread che rilascia il permesso lo trattiene effettivamente. Quando ho testato il mio codice di test, ho scoperto che questo potrebbe successivamente aumentare il numero di permessi oltre il limite iniziale. D'altra parte, se un thread non è in possesso di un blocco rientro quando invoca il metodo di sblocco, otteniamo un IllegalMonitorException.

Quindi sarebbe giusto dire che non esiste una vera ragione per avere un semaforo binario come tutto ciò che un semaforo binario può fare anche da un ReentrantLock. Se usiamo semafori binari dovremmo controllare l'intero stack di chiamate del metodo per vedere se un permesso è stato acquisito prima (anche se è stato rilasciato anche se c'è la possibilità di un successivo acquisto - che potrebbe bloccare se un rilascio non lo procede e presto). Inoltre, poiché i blocchi rientranti forniscono anche un blocco per oggetto, non è sempre meglio preferire un blocco di rientro a un semaforo binario?

Ho controllato qui un post che parla della differenza tra un semaforo binario e un mutex ma c'è qualcosa come un mutex in Java?

Grazie, Chan.

P.S - Avevo postato questa domanda in un altro forum (http://www.coderanch.com/t/615796/threads/java/reason-prefer-binary-Semaphore-Reentrant) e non ho ancora ricevuto una risposta. Ho pensato di pubblicarlo anche qui per vedere cosa posso ottenere.

+0

http://stackoverflow.com/questions/12641933/difference-between-semaphore-and-condition-reentrantlock può aiutare –

+2

Questo comportamento è di progettazione e [ben documentato] (http://docs.oracle.com/ JavaSE/7/docs/api/java/util/concorrente/Semaphore.html # rilascio% 28% 29): "* non è richiesto che un thread che rilascia un permesso deve aver acquisito tale permesso chiamando acquire() corretto. l'uso di un semaforo è stabilito dalla convenzione di programmazione nell'applicazione. * ". Quando si utilizza ReentrantLocks, è necessario assicurarsi di rilasciare correttamente il blocco in un blocco finale. Anche questo non è applicato, ma è ben documentato. – assylias

+1

Consulta anche: http://stackoverflow.com/questions/7554839/how-and-why-can-a-semaphore-give-out-more-permits-than-it-was-initialized-with – assylias

risposta

25

non v'è alcun motivo reale mai per avere un semaforo binario come tutto ciò che un semaforo binario può fare può anche essere fatto da un ReentrantLock

Se tutto ciò che serve è rientrante mutua esclusione, allora sì , non c'è motivo di usare un semaforo binario su un ReentrantLock. Se per qualsiasi motivo hai bisogno di semantiche non di proprietà, allora ovviamente il semaforo è la tua unica scelta.

Anche perché le serrature rientranti forniscono anche una serratura per oggetto, non è vero sempre una migliore idea di preferire un blocco rientrante a un semaforo binario?

Dipende dalla necessità. Come spiegato in precedenza, se hai bisogno di un mutex semplice, non scegliere un semaforo. Se più di un thread (ma un numero limitato) può entrare in una sezione critica, puoi farlo attraverso il thread-confinement o un semaforo.

Ho verificato un post qui che parla di differenza tra un semaforo binario e un mutex, ma c'è una cosa come un mutex in Java?

ReentrantLock e synchronized sono esempi di mutex in Java.

+1

Grazie, John. È stato rapido e utile. – Chan

3

Non spiegherò i blocchi di rientro dal momento che John ha già fornito una buona spiegazione sopra e un esempio di mutex in java con parola chiave sincronizzata.

Tuttavia, se per qualsiasi motivo, si desidera avere un controllo migliore sul meccanismo di blocco, il semaforo può diventare utile.Ciò significa che il tuo codice dovrà rimanere responsabile di chi ha chiamato acquire() e che ha chiamato release() poiché Semaphore per sua natura è cieco, tutto ciò che importa è che il permesso diventi disponibile.

Un altro approccio di una propria implementazione mutex usando Java è LockSupport. Funziona un po 'come Semaphore ma ha un timeout sul permesso, usando la funzione park() e supporta solo un permesso alla volta a differenza dei semafori che supportano più di essi.