Perché il mio thread si interrompe quando provo ad accedere a un elenco sincronizzato?

StackOverflow https://stackoverflow.com/questions/1824768

  •  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!

È stato utile?

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 ?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top