2010-02-26 4 views
3

J'ai un programme multi-thread, où j'ai un thread à surveiller sur plusieurs threads. Le fonctionnement est conçu comme ceci:addShutdownHook et setUncaughtExceptionHandler ne fonctionnent pas comme prévu dans Java

Programme principal fait initiation et commence Watcher fil, dans void main(), j'ai la ligne

Runtime.getRuntime().addShutdownHook(new Thread(new ShutdownThread(), "Exit Listener")); 

Quand je ne commence pas le fil de veilleur, le ShutdownThread est appelé quand je termine le programme, mais quand je démarre le thread Watcher qui a une boucle morte dedans, le ShutdownThread n'est pas appelé (j'imprime un message dans ce fil). C'est très très étrange. Des explications?

Le fil watcher est comme:

public void run(){ 
    boolean running=false; 
    thread a=new thread(...); //Do the same thing for b, c, d... 
    while(true){ 
    if (a.isActive()){ 
    if (running) 
     thread a= new thread(...); 
    a.start(); 
    running=true; 
    } 
    Thread.sleep(1000); //try catch block... 
} 

Ce que je voudrais est un arrêt gracieux, que lors de l'obtention d'un signal de fin, shutdownThread est exécuté, définit un indicateur et interrompt toutes les discussions, et attend les discussions pour l'interrompre, ou le timeout afin que les threads restants puissent être détruits. Tous les threads peuvent intercepter une interuption et vérifier si un indicateur est défini. Si elle est définie, elle interrompt shutdownThread et quitte ensuite elle-même. Au lieu de cela, ce que je vois, c'est que tous les fils se terminent par eux-mêmes, ne faisant aucun nettoyage.

Comment utiliser les signaux? Existe-t-il un bon code multiplateforme pour cela?

Ensuite, setUncaughtExceptionHandler ne fonctionne pas non plus. J'ai fait des tests et constaté que le gestionnaire n'est pas appelé du tout. Je ne sais pas pourquoi. Le code pour le gestionnaire est:

public static class ErrHandler implements Thread.UncaughtExceptionHandler{ 
    public final void uncaughtException(Thread t, Throwable e) { 
      Error(t + "died, threw exception: " + e); 
     } 
    }//this is in public class globals 

Je le crochet à l'aide

producer.setUncaughtExceptionHandler(Globals.errhandler); 

est dans mon code, et je ne voir le e.printStack d'origine() au lieu. Il semble que je ne peux pas le contourner, que ce soit dans le thread parent ou en lui-même. C'est tellement frustrant. Je pense mettre une entrée dans une file d'attente et la lire ailleurs. Au moins cela peut fonctionner. Oh, le but est de faire en sorte que si l'un des thread meurt à cause des exceptions d'exécution, le thread observateur vérifiera si l'exception est assez fatale, et décidera de redémarrer ce thread ou de quitter complètement. En même temps, je voudrais que le programme finisse gracieusement (une interruption est envoyée aux threads de sauvegarde pour qu'il vide les résultats, puis interrompt pour indiquer que nous sommes prêts à quitter) quand l'utilisateur le termine.

Répondre

0

Dunno si cela vous aide, mais nous avons rencontré le même comportement. Toutes les exceptions ne sont pas routées correctement vers ExceptionHandler enregistré.

Je me demande si Unit-Tests existe du tout pour l'infrastructure concurrente. Parce que cela devait être détecté.

Nous avons implémenté le ScheduledExecutorService par nous-mêmes en utilisant une instance ScheduledExecutorService en tant que délégué et en encapsulant le paramètre Runnable/Callable de chaque méthode dans une implémentation Runnable/Callable qui corrige le comportement.

Questions connexes