7
votes

Java - Arrêt de toutes les tâches dans ExecuTtorservice

J'ai quelques services exécutants qui planifiez des tâches locales telles que la lecture d'un fichier, la connexion à la DB, etc. Ces processus font une énorme quantité de journalisation, qui est étendue basée sur le fait qu'il y a de nombreux threads fonctionnant simultanément, écrivant leur propre chose dans le journal.

Maintenant, à un moment donné, une exception peut être soulevée, qui atteint la méthode principale où toutes les exceptions sont capturées. Je ferme ensuite tous les services et annulez chaque tâche, dans l'espoir d'éviter tout autre message au journal. Malheureusement, les messages s'affichent toujours après que j'ai tout fermé ... des idées? P>

Mise à jour: Voici un certain code P>

public class Scheduler{

private final ExecutorService service;
private final ConcurrentMap<Object, Future<V>> cache;

...

public void shutDown() {
    service.shutdownNow();
    for (Future task : cache.values())
        task.cancel(true);
}


2 commentaires

Donnez-nous un code si vous ne vous dérangeez pas. Toute journalisation de chances est faite de manière asynchrone? Utilisez-vous shutdown au lieu de shutdownnet ? Il y a une myriade de raisons.


Le fait que vous puissiez arrêter le service et annuler les tâches ne signifie pas que ces tâches s'arrêtent immédiatement.


4 Réponses :


0
votes

- Essayez d'utiliser la méthode shutdownow () , il arrêtera toute la tâche lancée par cet exécutant lancer interrompteException , mais Io et fonctionnement synchronisé ne peut pas être interrompu.

par exemple: xxx

- Annuler (true) La méthode peut être utilisée avec Soumettre () méthode sur Arrêter une tâche particulière. < / strong>


1 commentaires

C'est incorrect - ShutDownNow n'arrête pas les tâches, cela les interrompt, ce qui pourrait ou non les éteindre.



4
votes

Les exécuteurs soutiennent 2 approches d'arrêt

Arrêt () : initie une fermeture ordonnée dans laquelle les tâches soumises précédemment sont exécutées, mais aucune nouvelle tâche ne sera acceptée. L'invocation n'a aucun effet supplémentaire s'il est déjà arrêté.

shutdownnet () : tente d'arrêter toutes les tâches d'exécution actives, arrête le traitement des tâches en attente et renvoie une liste des tâches qui attendaient l'exécution. Il n'y a pas de garantie au-delà des tentatives des meilleurs efforts pour cesser de traiter activement des tâches d'exécution activement.

ref: http: //docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/executertorservice.html#shutDownNow ()


5 commentaires

Pas exactement - ShutdownNow n'arrête pas les tâches "avec force", cela ne les interrompt que, ce qui pourrait ou pourrait ne pas les arrêter.


D'accord @assylia. Modifiera mon message pour incorporer votre commentaire. Merci.


Donc, n'importe quand pour arrêter les tâches "avec force" ...?


Pourquoi voulez-vous forcer la fermeture? Ce n'est pas une bonne idée et c'est la raison pour laquelle Java ne fournit aucune méthode directe. (STOP / SUSPEND est obsolète)


Néanmoins, la meilleure réponse que j'ai trouvée jusqu'à présent. Fonctionne maintenant comme prévu. Merci encore



7
votes

Lorsque vous shutdownnet Votre exécuteur ou appelez Annuler (true) (à la manière suivante: shutdownow annule déjà les tâches déjà soumises afin que votre boucle soit inutile) Vos tâches sont interrompues.

Selon la manière dont ils réagissent à l'interruption, ils pourraient alors:

  • Arrêtez ce qu'ils font immédiatement
  • Arrêtez ce qu'ils font après un moment, car le signal d'interruption n'est pas vérifié assez régulièrement
  • Continuez à faire ce qu'ils font parce que le signal d'interruption a été ignoré

    Par exemple, si vos tâches exécutent un tandis que (vrai) boucle, vous pouvez le remplacer par quelque chose comme: xxx

    Un autre exemple: xxx

    Un autre exemple, si vous appelez une méthode qui jette une interruptionException: xxx


3 commentaires

@ Bober02 Dans vos tâches, vous devez vérifier régulièrement si le thread a été interrompu - lorsque vous détectez une interruption, nettoyez-la si nécessaire et quittez la tâche.


Je ne comprends pas ce tbh. Je soumets une tâche au service exécuteur, qui stocke à l'interne tous les threads. Tout ce que je peux faire, c'est utiliser l'API pour la fermer. Quels discussions surviennent?


@ Bober02 J'ai ajouté quelques exemples de vos runnables (tâches) pourraient ressembler - j'espère qu'il est plus clair maintenant.



10
votes

La tâche continuera à fonctionner jusqu'à ce qu'il atteigne un point où il détecte le fil a été interrompu. Cela peut arriver lors de l'appelant des fonctions système ou thread et vous pouvez obtenir une exception projetée. Dans votre cas, vous devez probablement vous vérifier en appelant

fil.currentThread (). Isinterrupted ()

C'est une bonne idée de le faire si votre code exécute des boucles et que vous vous attendez à être arrêté de cette manière.


0 commentaires