Comment dois-je choisir entre la soumission ou l' exécution d' ExecutorService , si la valeur renvoyée ne me concerne pas?
Si je teste les deux, je n'ai vu aucune différence entre les deux, sauf la valeur renvoyée.
ExecutorService threadExecutor = Executors.newSingleThreadExecutor();
threadExecutor.execute(new Task());
ExecutorService threadExecutor = Executors.newSingleThreadExecutor();
threadExecutor.submit(new Task());
la source
Runnable
dans unTask
, sur lequel vous n'avez peut-être aucun contrôle. Par exemple, si votreExecutor
est en fait unScheduledExecutorService
, votre tâche sera encapsulée en interne dans aFuture
et les non interceptésThrowable
seront liés à cet objet.Future
ou pas», bien sûr. Voir le Javadoc pour ScheduledThreadPoolExecutor # execute , par exemple.exécuter : utilisez-le pour tirer et oublier les appels
submit : utilisez-le pour inspecter le résultat de l'appel de méthode et prendre les mesures appropriées sur l'objet
Future
renvoyé par l'appelde javadocs
submit(Callable<T> task)
Future<?> submit(Runnable task)
Vous devez prendre des précautions lors de l'utilisation
submit()
. Il masque l'exception dans le cadre lui-même, sauf si vous incorporez votre code de tâche dans untry{} catch{}
bloc.Exemple de code: Ce code avale
Arithmetic exception : / by zero
.production:
Le même code lève en remplaçant
submit()
parexecute
():Remplacer
avec
production:
Comment gérer ces types de scénarios lors de l'utilisation de submit ()?
CustomThreadPoolExecutor
Nouvelle solution:
production:
la source
si vous ne vous souciez pas du type de retour, utilisez execute. c'est la même chose que soumettre, juste sans le retour de Future.
la source
Tiré du Javadoc:
Personnellement, je préfère l'utilisation d'exécuter parce que cela semble plus déclaratif, bien que ce soit vraiment une question de préférence personnelle.
Pour donner plus d'informations: dans le cas de l'
ExecutorService
implémentation, l'implémentation principale renvoyée par l'appel àExecutors.newSingleThreadedExecutor()
est unThreadPoolExecutor
.Les
submit
appels sont fournis par son parentAbstractExecutorService
et tous les appels s'exécutent en interne. execute est remplacé / fourni parThreadPoolExecutor
directement.la source
Depuis le Javadoc :
Ainsi, en fonction de l'implémentation de,
Executor
vous constaterez peut-être que le thread de soumission se bloque pendant l'exécution de la tâche.la source
La réponse complète est une composition de deux réponses qui ont été publiées ici (plus un peu "extra"):
execute
(car son identifiant de type de retourvoid
)execute
attend unRunnable
momentsubmit
peut prendre unRunnable
ou unCallable
comme argument (pour plus d'informations sur la différence entre les deux - voir ci-dessous).execute
bulles vers le haut toutes les exceptions non vérifiées tout de suite (il ne peut pas lancer d'exceptions vérifiées !!!), tandis quesubmit
lie tout type d'exception au futur qui retourne en conséquence, et seulement lorsque vous appelezfuture.get()
une exception (encapsulée) sera levée. Le Throwable que vous obtiendrez est une instance deExecutionException
et si vous appelez cet objetgetCause()
il renverra le Throwable d'origine.Quelques autres points (liés):
submit
ne nécessite pas de retourner un résultat, vous pouvez toujours utiliserCallable<Void>
(au lieu d'utiliser unRunnable
).Pour résumer, c'est une meilleure pratique à utiliser
submit
avec aCallable
(plutôtexecute
qu'avec aRunnable
). Et je citerai «la concurrence Java en pratique» de Brian Goetz:la source
Juste en ajoutant à la réponse acceptée-
La source
la source