Différence entre shutdown et shutdownow du service D'exécuteur testamentaire

je veux connaître la différence fondamentale entre shutdown() et shutdownNow() pour fermer le Executor Service ?D'après ce que j'ai compris, shutdown() devrait être utilisé pour arrêt gracieux ce qui signifie que toutes les tâches qui étaient en cours d'exécution et la file d'attente pour le traitement, mais pas commencé, devrait être autorisé à terminer et shutdownNow() fait un arrêt brusque ce qui signifie que certaines tâches non terminées sont annulées et les tâches non commencées sont également annulées . Est-il autre chose qui est implicite/explicite que je suis absent ?

P. S: j'ai trouvé une autre question sur SO liée à cela, mais pas exactement ce que je veux savoir .

53
demandé sur Community 2012-07-17 14:02:09

3 réponses

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

  • shutdown() "va simplement dire au service exécuteur qu'il ne peut pas accepter de nouvelles tâches, mais les tâches déjà soumises continuent à courir
  • shutdownNow() fera la même chose et tentera d'annuler les tâches déjà soumises en interrompant les threads pertinents. Notez que si vos tâches ne tiennent pas compte de l'interruption, shutdownNow se comportera exactement de la même façon comme shutdown .

vous pouvez essayer l'exemple ci-dessous et remplacer shutdown par shutdownNow pour mieux comprendre les différentes voies d'exécution:

  • avec shutdown , la sortie est Still waiting after 100ms: calling System.exit(0)... parce que la tâche en cours d'exécution est et non interrompu et continue à courir.
  • avec shutdownNow , la sortie est interrupted et Exiting normally... parce que la tâche d'exécution est interrompu, saisit l'interruption puis arrête ce qu'il fait (casse la boucle while).
  • avec shutdownNow , si vous commentez les lignes dans la boucle while, vous obtiendrez Still waiting after 100ms: calling System.exit(0)... parce que 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...");
}
99
répondu assylias 2012-07-17 10:19:28
  • shutdown() :

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

  • shutdownNow() :

si vous voulez arrêter l'Exécutorservice immédiatement, vous pouvez appeler la méthode shutdownNow() . Cela va essayer d'arrêter toutes les tâches d'exécution tout de suite, et saute toutes les tâches soumises mais non traitées. Aucune garantie n'est donnée quant aux tâches d'exécution. Peut-être qu'ils arrêteront, peut-être l'exécution jusqu'à la fin. Il est possible de tenter.

3
répondu Ahmed MANSOUR 2015-09-15 10:00:33

De la javadoc :

void shutdown

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

List<Runnable> shutdownNow()

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

Il y a non garantie au-delà de best-effort des tentatives d'arrêt traitement actif exécuter des tâches.

par exemple, les implémentations typiques s'annuleront via Fil.interrupt(), toute tâche qui ne répond pas aux interruptions peut ne jamais se terminer.

Retourne: liste des tâches qui n'a jamais commencé "l'exécution 151950920"

2
répondu fmucar 2015-07-22 14:03:06