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.