Si l'utilisation de invokeAll ou soumettez - java Exécuteur service
J'ai un scénario où je dois exécuter 5 thread asynchrone pour la même appelable. Comme je le comprends, il y a deux options:
1) à l'aide de soumettre(Rachetable)
ExecutorService executorService = Executors.newFixedThreadPool(5);
List<Future<String>> futures = new ArrayList<>();
for(Callable callableItem: myCallableList){
futures.add(executorService.submit(callableItem));
}
2) à l'aide de invokeAll(Collections de Callable)
ExecutorService executorService = Executors.newFixedThreadPool(5);
List<Future<String>> futures = executorService.invokeAll(myCallableList));
- Ce qui devrait être le moyen privilégié?
- Est-il un désavantage ou d'impact sur les performances dans l'un d'eux par rapport à l'autre?
Vous devez vous connecter pour publier un commentaire.
Option 1 : Vous présentez les tâches à
ExecutorService
et vous n'êtes pas d'attendre l'achèvement de toutes les tâches qui ont été soumises àExecutorService
Option 2 : Vous êtes en attente de l'achèvement de toutes les tâches qui ont été soumises à
ExecutorService
.Selon les exigences de la demande, l'un d'eux est préféré.
ExecutorService
, préférezOption 1
.ExecutorService
, préférezOption 2
.Si votre application nécessite l'Option 2, vous devez attendre la fin de toutes les tâches à
ExecutorService
contrairement à l'Option 1. Les performances ne sont pas des critères de comparaison que les deux sont conçus pour deux raisons différentes.Et une chose plus importante : Quelle que soit l'option que vous préférez,
FutureTask
avale des Exceptions lors de l'exécution de la tâche. Vous devez être prudent. Jetez un oeil à cette question SE: La gestion des Exceptions pour ThreadPoolExecutorAvec Java 8, vous avez une option de plus : ExecutorCompletionService
Regarder liées SE question : ExecutorCompletionService? Pourquoi en avez besoin, si nous avons invokeAll?
EDIT:
Il y a effectivement une différence entre eux. Pour une raison quelconque,
invokeAll()
appelleraget()
pour chaquefuture
produit. Ainsi, il faudra attendre les tâches à terminer et c'est pourquoi il peut jeterInterruptedException
(alors quesubmit()
jette rien).C'est la Javadoc de la
invokeAll()
méthode:Donc, les deux stratégies fondamentalement faire de même, mais si vous appelez
invokeAll()
vous serez bloqué jusqu'à ce que toutes les tâches sont effectuées.D'origine (incomplet) réponse:
La
invokeAll()
méthode est-il exactement pour des situations comme celles-ci. Vous devriez certainement utiliser.Vous n'avez pas vraiment besoin d'instancier que
List
, si:Cela devrait être suffisant, et il ressemble de manière plus propre que la première alternative.
Supposons que vous avez une tâche dont le résultat dépend du nombre de independentaly exécutable tâches. Mais pour la première tâche à effectuer vous que de peu de temps. Comme le son d'un appel d'API.
Ainsi, par exemple, vous avez 100ms de haut niveau de la tâche à accomplir et il y a 10 personne à charge aussi bien les tâches. Pour que si vous utilisez une présenter ici comment le code ressemblera.
Donc, si chacune des sous-tâches a pris exactement 50ms pour compléter le ci-dessus morceau de code prendrait 50 ms.
Mais si chacune des sous-tâches a pris 1000 ms pour compléter la partie ci-dessus, prenez 100 * 10 = 1000 ms ou 1s. C'est ce qui rend difficile de calculer le temps total à moins de 100ms pour toutes les sous-tâches.
invokeAll méthode nous aide dans un tel scénario
De cette façon, le temps maximum qu'il est intérieurement 100 ms même si la personne de sous-tâches a pris plus que cela.
future.get(100, TimeUnit.MILLISECONDS);
encore du travail, ce n'est pas que nous voulons.