Ogni volta che hai più serrature A, B e C puoi avere Deadlock se non garantisci che il tuo codice tenta di acquisire tali serrature nello stesso ordine.
final Lock A = new ReentrantLock();
final Lock B = new ReentrantLock();
final Lock C = new ReentrantLock();
A, B, C o C, B, A o A, C, B - Non importa fintanto che l'ordine è coerente.
Un problema sorge quando hai un percorso di codice per: A, B, C e un altro che prova per C, B, A.
Come puoi probabilmente indovinare poiché A e C vengono detenuti entrambi, uno dei due otterrà B e poi entrambi saranno deadlock. (Aka hai un ciclo nel grafico di bloccaggio delle risorse)
Può sorgere la stallo formalmente parlando solo se Tutte le seguenti condizioni contengono:
- Nessuna precettazione: il sistema non libererà risorse dopo l'allocazione; Possono essere rilasciati solo dal processo di detenzione.
- Aspetta circolare: discusso sopra.
- Esclusione reciproca: solo un processo può utilizzare una risorsa in qualsiasi momento.
- Holding delle risorse: un processo ha attualmente almeno una risorsa e richiede/attendendo risorse aggiuntive che sono detenute da un altro processo.
La soluzione migliore è assicurarsi che l'ordine sia coerente o blocca a un livello più alto (singolo). Un'altra opzione è quella di utilizzare una libreria di bloccaggio che si time mentre si tenta di bloccare (o utilizzare le condizioni e scrivere il proprio wrapper che lo fa). Ma quell'approccio non è per i deboli di cuore. Una certa implementazione di questo aspetterà un periodo di tempo casuale e riproverà, ma questo può essere altamente inefficiente all'aumentare del numero di blocchi.
Risorse:
- Ecco un articolo pratico sull'analisi del deadlock in Java a cui potresti essere interessato:http://www.journaldev.com/1058/java-deadlock-example-and-how-to-analyze-deadlock-situation
- Puoi anche usare strumenti open source come JCarder per trovare Deadlock:http://www.jcarder.org/ Che per programmi con dump di grandi dimensioni può essere più semplice, quindi provare a far sfuggire i file di dump.
PS in realtà non ho letto gran parte del tuo codice poiché è scarsamente formattato e non è un esempio minimo (cioè troppo verboso per i nostri scopi qui). Ma questo consiglio dovrebbe rispondere alla tua domanda dal punto di vista teorico.