web-dev-qa-db-fra.com

Différence entre l'arrêt et l'arrêt maintenant du service d'exécution

Je veux connaître la différence fondamentale entre shutdown() et shutdownNow() pour arrêter le Executor Service? Pour autant que je sache, shutdown() doit être utilisé pour arrêt progressif ce qui signifie que toutes les tâches en cours d'exécution et mises en file d'attente pour le traitement mais non démarrées doivent être autorisées à se terminer et shutdownNow() fait un arrêt brutal signifiant que certaines tâches non terminées sont annulées et que les tâches non démarrées sont également annulées. Y a-t-il autre chose implicite/explicite qui me manque?

P.S: J'ai trouvé une autre question sur DONC en rapport avec cela mais pas exactement ce que je veux savoir.

62
Geek

En résumé, vous pouvez y penser de cette façon:

  • shutdown() indiquera simplement au service exécuteur qu'il ne peut pas accepter de nouvelles tâches, mais les tâches déjà soumises continuent de s'exécuter
  • shutdownNow() fera de même ET essayera d'annuler les tâches déjà soumises en interrompant les threads appropriés. Notez que si vos tâches ignorent l'interruption, shutdownNow se comportera exactement de la même manière que shutdown.

Vous pouvez essayer l'exemple ci-dessous et remplacer shutdown par shutdownNow pour mieux comprendre les différents chemins d'exécution:

  • avec shutdown, la sortie est Still waiting after 100ms: calling System.exit(0)... car la tâche en cours est pas interrompue et continue de s'exécuter.
  • avec shutdownNow, la sortie est interrupted et Exiting normally... car la tâche en cours est interrompue, intercepte l'interruption puis arrête ce qu'elle fait (rompt la boucle while).
  • avec shutdownNow, si vous commentez les lignes dans la boucle while, vous obtiendrez Still waiting after 100ms: calling System.exit(0)... car l'interruption n'est plus gérée par la tâche en cours d'exécution.
public static void main(String[] args) throws InterruptedException {
    ExecutorService executor = Executors.newFixedThreadPool(1);
    executor.submit(new Runnable() {

        @Override
        public void run() {
            while (true) {
                if (Thread.currentThread().isInterrupted()) {
                    System.out.println("interrupted");
                    break;
                }
            }
        }
    });

    executor.shutdown();
    if (!executor.awaitTermination(100, TimeUnit.MICROSECONDS)) {
        System.out.println("Still waiting after 100ms: calling System.exit(0)...");
        System.exit(0);
    }
    System.out.println("Exiting normally...");
}
116
assylias
  • shutdown():

Pour terminer les threads à l'intérieur de l'ExecutorService, vous appelez sa méthode shutdown(). L'ExecutorService ne s'arrêtera pas immédiatement, mais il n'acceptera plus de nouvelles tâches, et une fois que tous les threads auront terminé les tâches en cours, l'ExecutorService s'arrêtera. Toutes les tâches soumises à ExecutorService avant l'appel à shutdown () sont exécutées.

  • shutdownNow():

Si vous souhaitez arrêter immédiatement ExecutorService, vous pouvez appeler la méthode shutdownNow(). Cela tentera d'arrêter immédiatement toutes les tâches en cours d'exécution et ignorera toutes les tâches soumises mais non traitées. Il n'y a aucune garantie donnée sur les tâches d'exécution. Peut-être qu'ils s'arrêtent, peut-être l'exécution jusqu'à la fin. Il s'agit d'une tentative de meilleur effort.

5
Ahmed MANSOUR

Depuis javadocs :

void shutdown

Lance un arrêt ordonné dans lequel les tâches soumises précédemment sont exécutées, mais aucune nouvelle tâche ne sera acceptée.

List<Runnable> shutdownNow()

Tente d'arrêter toutes les tâches en cours d'exécution, arrête le traitement des tâches en attente et renvoie une liste des tâches en attente d'exécution.

Il n'y a aucune garantie au-delà des tentatives d'effort pour arrêter le traitement activement exécution des tâches.

Par exemple, les implémentations typiques seront annulées via Thread.interrupt (), de sorte que toute tâche qui ne répond pas aux interruptions peut ne jamais se terminer.

Retours: liste des tâches dont l'exécution n'a jamais commencé

2
fmucar