L'exécuteur semble être une abstraction propre. Quand voudriez-vous utiliser directement Thread plutôt que de vous fier à l'exécuteur plus robuste?
Pour donner un peu d'histoire, les exécuteurs n'ont été ajoutés que dans le cadre de la norme Java dans Java 1.5. Ainsi, à certains égards, les exécuteurs peuvent être considérés comme une nouvelle meilleure abstraction). pour gérer les tâches exécutables.
Un peu de simplification à venir ... - Les exécuteurs sont des threads bien faits, alors utilisez-les de préférence.
J'utilise Thread lorsque j'ai besoin d'un traitement de message basé sur l'extraction. Par exemple. une file d'attente est take () - en en boucle dans un thread séparé. Par exemple, vous encapsulez une file d'attente dans un contexte coûteux - disons une connexion JDBC, une connexion JMS, des fichiers à traiter à partir d'un seul disque, etc.
Avant d'être maudit, avez-vous un scénario?
Modifier :
Comme indiqué par d'autres, l'interface Executor
(ExecutorService
) a plus de potentiel, car vous pouvez utiliser Executors
pour sélectionner un comportement: planifié, priorisé, mis en cache, etc. dans = Java 5+ ou un backport juc pour Java 1.4.
Le cadre de l'exécuteur est protégé contre les exécutables exécutables et recrée automatiquement les threads de travail. Un inconvénient à mon avis, que vous devez explicitement shutdown()
et awaitTermination()
avant de quitter votre application - ce qui n'est pas si facile dans les applications GUI. Si vous utilisez des files d'attente limitées, vous devez spécifier un RejectedExecutionHandler
ou les nouveaux runnables seront jetés.
Vous pourriez jeter un œil à Brian Goetz et al: Java Concurrence in Practice (2006)
Il n'y a aucun avantage à utiliser des threads bruts. Vous pouvez toujours fournir aux exécuteurs une usine de threads, de sorte que même l'option de création de threads personnalisée est couverte.
Vous n'utilisez pas Thread sauf si vous avez besoin d'un comportement plus spécifique qui ne se trouve pas dans Thread lui-même. Vous étendez ensuite Thread et ajoutez votre comportement spécifiquement souhaité.
Sinon, utilisez simplement Runnable ou Executor.
Eh bien, je pensais qu'un ThreadPoolExecutor offrait de meilleures performances car il gérait un pool de threads, minimisant la surcharge d'instanciation d'un nouveau thread, d'allocation de mémoire ...
Et si vous allez lancer des milliers de threads, cela vous donne des fonctionnalités de mise en file d'attente que vous devrez programmer vous-même ...
Threads & Executors sont différents outils, utilisés dans différents scénarios ... Comme je le vois, c'est comme demander pourquoi devrais-je utiliser ArrayList quand je peux utiliser HashMap? Ils sont différents...
Le package Java.util.concurrent fournit une interface d'exécuteur et peut être utilisé pour créer un thread.
L'interface Executor fournit une méthode unique, execute, conçue pour être un remplacement direct pour un idiome de création de threads commun. Si r est un objet exécutable et e est un objet exécuteur, vous pouvez remplacer
(nouveau fil (r)). start ();
avec
e.execute (r);
Voir ici
Il est toujours préférable de préférer Executor à Thread
même pour un seul thread comme ci-dessous
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(1);
Vous pouvez utiliser Thread
sur Executor
dans les scénarios ci-dessous
Votre application a besoin d'un nombre limité de threads et la logique métier est simple
Si le modèle simple multi-threading répond à vos besoins sans Thread Pool
Vous êtes sûr de gérer le cycle de vie des threads + les scénarios de gestion des exceptions à l'aide d'API de bas niveau dans les domaines ci-dessous: Inter thread communication, Exception handling, reincarnation of threads
en raison d'erreurs inattendues
et un dernier point
Si votre application n'a pas besoin de personnalisation de diverses fonctionnalités de ThreadPoolExecutor
ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime,
TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory,
RejectedExecutionHandler handler)
Dans tous les autres cas, vous pouvez opter pour ThreadPoolExecutor