Perché il mio thread si interrompe quando provo ad accedere a un elenco sincronizzato?
-
22-07-2019 - |
Domanda
Per qualche motivo, l'output di questo:
public void msgNeedParts() {
// Blabla...
System.out.println(name + ": Try to print 'tasks'...");
synchronized(tasks) {
System.out.println(name + ": Tasks--" + tasks);
System.out.println(name + ": Did I manage to print it?");
tasks.add(new BinToDump(feeder, binNum));
}
stateChanged();
}
Stampa solo " GantryAgent: prova a stampare "task" ... " ma nessuno dei seguenti messaggi. Sto indovinando il thread in qualche modo "si blocca" quando si tenta di accedere all'elenco sincronizzato "attività", ma non so perché questo accada.
'task' è stato dichiarato e inizializzato in questo modo:
private List<BinToDump> tasks =
Collections.synchronizedList(new ArrayList<BinToDump>());
Qualcuno può far notare ciò che mi manca?
Ah! Sospetto di avere un colpevole:
/* If nothing left to do, return to original position. */
synchronized (tasks) {
if (tasks.isEmpty()) {
doReturnToOriginalPos();
}
}
Nel mio scheduler (questo è un design di agente), controllo se 'task' è vuoto, quindi chiamo doReturnToOriginalPos (). Forse questo sta accadendo più e più volte così velocemente che altri metodi non hanno la possibilità di modificarlo?
Questo era davvero il problema! Continuava a essere chiamato così velocemente nel mio programmatore che nient'altro poteva accedere alle "attività". Grazie a tutti per l'aiuto!
Soluzione
Qualcosa ha un blocco nelle attività. A seconda del tipo di applicazione, si dovrebbe essere in grado di ottenere un dump dello stack completo del sistema, ma il metodo varia. Ad esempio, penso che CTRL-Break sulla maggior parte dei appserver basati su Windows farà questo, e penso che l'invio di un SIGQUIT su Linux farà lo stesso.
Una volta ottenuto un dump dello stack, puoi guardarlo attraverso per provare a scoprire quale altro thread ha un blocco su quell'oggetto.
Puoi anche utilizzare VisualVM per ottenere un dump dello stack, per lo stesso obiettivo finale:
Puoi usare Java VisualVM per prendere a dump del thread (traccia stack) mentre a l'applicazione locale è in esecuzione. Prendendo a il dump del thread non interrompe il file applicazione. Quando si stampa il filo dump ottieni una stampa del thread stack che include stati del thread per i thread Java.
Quando si stampa un dump del thread in Java VisualVM, lo strumento stampa una pila traccia dei thread attivi di applicazione. Utilizzando Java VisualVM per prendere un dump del thread può essere molto conveniente nei casi in cui non lo fai avere una console a riga di comando per il applicazione. È possibile utilizzare una traccia dello stack per aiutare a diagnosticare una serie di problemi come deadlock o quando un l'applicazione si blocca.
Altri suggerimenti
È possibile che un altro thread mantenga un blocco di sincronizzazione su task
?