web-dev-qa-db-fra.com

Quand devrions-nous utiliser Thread over Executor de Java?

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?

53
ripper234

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.

30
Pablojim

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)

7
akarnokd

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.

5
skaffman

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.

3
nojevive

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...

3
SoulWanderer

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

3
challenger

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

  1. Votre application a besoin d'un nombre limité de threads et la logique métier est simple

  2. Si le modèle simple multi-threading répond à vos besoins sans Thread Pool

  3. 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

  1. 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

2
Ravindra babu