Selon la concurrence Java de Brian Goetz dans la pratique JVM ne peut pas quitter tant que tous les threads (Nondaemon) se sont terminés, alors omis de désactiver un exécuteur pouvant empêcher le JVM de sortir. em> C'est à dire System.exit (0) ne fonctionne pas nécessairement comme prévu s'il y a des exécuteurs autour. Il semblerait nécessaire de mettre une sorte de méthodes p> à toutes les classes contenant des exécuteurs, puis les appeler lorsque l'application est sur le point de se terminer. Est-ce le seul moyen, ou existe-t-il une sorte de raccourci pour arrêter tous les exécuteurs? P> P>
5 Réponses :
Probablement il voulait dire que JVM ne peut pas s'arrêter seul jusqu'à la fin des fils Nondaemon. C'est comme exécuter une classe simple de la commande comme Java Somlass et après l'exécution de la méthode principale des arrêts JVM. P>
System.exit est une commande de terminaison JVM, même si les threads du démon sont en cours d'exécution, JVM sera arrêté. P>
Comme l'a écrit Goetz, Les threads Nondaemon i> peuvent empêcher JVM de sortir. En fait j'ai vécu cela. Le débogueur montre que l'application peut coincer à System.exit (0) infiniment, mais il semble être un comportement non déterministe. Habituellement, ça ne confie pas, mais parfois ça fait.
Il n'y a pas de raccourci pour les faire tous, non. En outre, vous devriez probablement appeler Ce que vous pouviez faire, je suppose, est lorsque vous créez l'exécuteur, enregistrez-le dans un endroit central. Ensuite, lors de la fermeture, appelez simplement Si vous utilisez le printemps, vous pouvez profiter de ses haricots d'usine qui créent et gèrent les exécuteurs pour vous. Cela inclut la fermeture gracieusement lorsque l'application quitte et vous sauve que vous devez les gérer vous-même. P> shutdownnet () code> plutôt que arrêt () code>, sinon vous pourriez attendre un moment. P>
arrêt () code> sur cet objet central, qui pourrait à son tour mettre fin à chacun des exécuteurs enregistrés. P>
Le registre central semble être une option raisonnable. Drôle que java.util.concurrent n'inclut pas telle.
Il est également dommage que les exécuteurs soient juste un groupe de statistiques, ce qui permet de le cacher derrière une interface d'enregistrement sans dupliquer plusieurs douzaines de signatures de méthodes.
Je suis également confronté à un problème similaire. Je ne suis pas explicitement à l'aide de planifiéesTheadpoolexecutor. Donc, je n'ai aucune référence centrale à la même chose. Dans un tel cas, comment accéder à ces threadpools? J'essaie de les arrêter gracieusement dans la méthode contextuelle
Vous pouvez également fournir une implémentation de la filefactoire qui marque des threads créés comme threads de démon. Je préfère un mécanisme d'arrêt propre (avec des méthodes de cycle de vie), mais il y a des cas où vous n'avez pas besoin de garanties sur l'état / l'achèvement des tâches sans réserve lorsque cela peut être approprié. P>
Merci d'avoir souligné cette option. En fait, certains de mes exécuteurs devraient être des fils de démon, ils devraient simplement être des non-démon, car c'est ce que les exécutants.newxxxexecutor (): s font par défaut.
Par défaut, un exécuteur ne créera que des threads non-démon. Vous pouvez remplacer cela en fournissant l'exécuteur exécutant avec votre propre filefactoire. Voici un exemple:
class DaemonThreadFactory implements ThreadFactory {
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setDaemon(true);
return t;
}
}
Décorez l'exécuteur exécutant avec com.google.common.util.concurrent.moreExecuts # GetExitexecutetorservice
@Beta
public static ExecutorService getExitingExecutorService(ThreadPoolExecutor executor,
long terminationTimeout,
TimeUnit timeUnit)
J'étais confusant exécuteur avec Runnable. J'ai supprimé ma réponse car il n'a pas beaucoup de sens. @skaffman a mon vote.