Pourquoi mon thread s'arrête-t-il lorsque j'essaie d'accéder à une liste synchronisée?

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

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

Était-ce utile?

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 ?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top