Pourquoi mon thread s'arrête-t-il lorsque j'essaie d'accéder à une liste synchronisée?
-
22-07-2019 - |
Question
Pour une raison quelconque, la sortie de ceci:
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();
}
Vous venez d'imprimer "GantryAgent: essayez d'imprimer des" tâches "... " mais pas l'un des messages suivants. J'imagine que le fil de discussion se «bloque» lorsque vous essayez d'accéder aux «tâches» de la liste synchronisée, mais je ne sais pas pourquoi cela se produit.
'tâches' a été déclaré et initialisé comme suit:
private List<BinToDump> tasks =
Collections.synchronizedList(new ArrayList<BinToDump>());
Quelqu'un peut-il signaler ce que je manque?
Ah! Je soupçonne d’avoir un coupable:
/* If nothing left to do, return to original position. */
synchronized (tasks) {
if (tasks.isEmpty()) {
doReturnToOriginalPos();
}
}
Dans mon ordonnanceur (il s'agit d'une conception d'agent), je vérifie si les "tâches" sont vides, puis j'appelle doReturnToOriginalPos (). Peut-être que cela se produit encore et encore si vite que d’autres méthodes n’ont pas la chance de le modifier?
C'était bien le problème! Mon ordonnanceur appelait si vite que rien d'autre ne pouvait accéder aux «tâches». Merci à tous pour l'aide!
La solution
Quelque chose a un verrou sur les tâches. Selon le type d'application utilisé, vous devriez pouvoir obtenir un vidage complet de la pile du système, mais la méthode varie. Par exemple, je pense que CTRL-Break fonctionnera de la même manière sur la plupart des serveurs d'applications Windows, et je pense que l'envoi d'un SIGQUIT sur linux fera de même.
Une fois que vous obtenez un vidage de pile, vous pouvez le parcourir pour essayer de trouver quel autre thread a un verrou sur cet objet.
Vous pouvez également utiliser VisualVM . obtenir un dump de pile, pour le même objectif final:
Vous pouvez utiliser Java VisualVM pour prendre thread dump (trace de la pile) lorsqu’un application locale est en cours d'exécution. Prendre un le vidage de fil n'arrête pas le application. Quand vous imprimez le fil dump vous obtenez une impression du fil pile qui inclut les états de thread pour les threads Java.
Lorsque vous imprimez un cliché de thread en Java VisualVM, l'outil imprime une pile trace des threads actifs du application. Utiliser Java VisualVM pour prendre une décharge de fil peut être très pratique dans les cas où vous ne le faites pas avoir une console de ligne de commande pour le application. Vous pouvez utiliser une trace de pile pour aider à diagnostiquer un certain nombre de problèmes tels que les impasses ou quand un l'application se bloque.
Autres conseils
Est-il possible qu'un autre thread maintienne un verrou de synchronisation contre les tâches
?