Quelle est la différence entre
ExecutorService eService = Executors.newFixedThreadPool(2);
eService.execute(new TestThread6());
eService.execute(new TestThread6());
eService.execute(new TestThread6());
eService.awaitTermination(1, TimeUnit.NANOSECONDS);
eService.shutdown();
et
eService.shutdown();
eService.awaitTermination(1, TimeUnit.NANOSECONDS);
Je ne comprends pas vraiment shutdown()
. Cette méthode n'attend pas l'exécution des tâches précédemment soumises. Cela signifie-t-il que shutdown()
peut mettre fin aux tâches qui ont été soumises, mais pas terminées? J'ai essayé quelques exemples, ils ne le prouvent pas, donnez-moi un exemple.
Vous devez d'abord appeler shutdown
. Sinon, vous pourriez attendre très longtemps, car awaitTermination
ne ferme pas réellement votre exécuteur.
Si vous souhaitez attendre la fin des tâches plutôt que d'attendre que l'exécuteur s'arrête, vous devez utiliser invokeAll
.
La lecture de la documentation aide toujours:
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. Ces tâches sont vidées (supprimées) de la file d'attente des tâches au retour de cette méthode.
Cette méthode n'attend pas la fin active des tâches. Utilisez waitTermination pour ce faire.
Il n'y a aucune garantie au-delà des tentatives au mieux pour arrêter le traitement des tâches en cours d'exécution. Cette implémentation annule les tâches via Thread.interrupt (), donc toute tâche qui ne répond pas aux interruptions peut ne jamais se terminer
arrêt :
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. L'invocation n'a aucun effet supplémentaire si elle est déjà arrêtée.
Cette méthode n'attend pas l'exécution des tâches précédemment soumises. Utilisez
awaitTermination
pour ce faire.
Bloque jusqu'à ce que toutes les tâches soient terminées après une demande d'arrêt , que le délai d'expiration se produise ou que le thread en cours soit interrompu, selon la première éventualité.
shutdown signifie que le service exécuteur ne prend plus de tâches entrantes.
waitTermination est invoqué après une demande d'arrêt.
Vous devez d'abord arrêter le service, puis bloquer et attendre la fin des threads.
Si vous souhaitez voir tous les threads terminer leur exécution et insister sur l'utilisation de awaiTermination
, vous devez définir le paramètre de délai d'attente pour qu'il soit suffisamment grand. Vous pourriez donc faire:
eService.shutdown();
if (!eService.awaitTermination(60000, TimeUnit.SECONDS))
System.err.println("Threads didn't finish in 60000 seconds!");
}
Alternativement, vous pouvez faire:
eService.shutdown();
while (!eService.isTerminated()) {
}
De cette façon, vous pouvez vous assurer que tous les threads sont terminés, sauf s'ils sont interrompus de manière inattendue.
Après avoir démarré la première tâche, ThreadPoolExecutor démarrera un thread qui ne se terminera pas même après la fin de la tâche. Au moins, c'est vrai pour un pool de threads fixe. C'est pourquoi nous devons appeler l'arrêt. Après l'arrêt, ThreadPoolExecutor rejettera toute nouvelle tâche mais attendra la fin des tâches en cours, puis autorisera la fin des threads. C'est pourquoi nous avons besoin de waitTermination après shutdwon.
executorService.execute(runnableTask);
//executorService.shutdown(); //it will make the executorService stop accepting new tasks
//executorService.shutdownNow(); //tires to destroy the executorService immediately, but it doesn't guarantee that all the running threads will be destroyed at the same time. This method returns list of tasks which are waiting to be processed.
//List<Runnable> notExecutedTasks = executorService.shutdownNow(); //this method returns list of tasks which are waiting to be processed.developer decide what to do with theses tasks?
//one good way to shutdown the executorService is use both of these methods combined with the awaitTermination
executorService.shutdown();
try{
if(!executorService.awaitTermination(1000, TimeUnit.MICROSECONDS)) {
executorService.shutdownNow();
}
}catch (InterruptedException e){
e.printStackTrace();
}
différence principale
shutdown () -
1. Not block the calling a thread - means a thread who called the shutdown().
2. Excecutor not accepting new task after calling shutdown().
waitTermination -
1. Block the calling thread. (as join() method do)
Confusion Point - parce que shutdown () ne tue pas la tâche soumise précédemment, alors pourquoi attendreTermination ()
shutdown () ne tue également aucune tâche qui a été soumise précédemment signifie que les tâches soumises et les tâches en cours d'exécution sont autorisées à continuer, alors pourquoi avoir besoin de waitTermination ().
Supposons que vous puissiez attendre 10 min uniquement pour terminer toutes les tâches qui sont soumises et ensuite que vous souhaitez appeler shutdownNow () (--- vous savez déjà ce qu'il fait), puis utilisez waitTermination () après avoir appelé fermer().
Et s'il n'y a pas de restriction de temps, alors shutdown () est ok. Pas besoin de waitTermination ().
Depuis Java8 ThreadPool, méthode waitTermination:
try {
for (;;) {
if (runStateAtLeast(ctl.get(), TERMINATED))
return true;
if (nanos <= 0)
return false;
nanos = termination.awaitNanos(nanos);
}
} finally {
mainLock.unlock();
}
Il vérifiera d'abord l'état d'exécution du pool de threads. Et si le pool de threads n'est pas arrêté (qui définit l'état d'exécution sur Terminé), la méthode waitTermination ne reviendra pas avant le délai d'expiration. Cela explique pourquoi attendre longtemps si vous attendez d'abord puis l'arrêt.