2009-01-03 14 views
221

J'ai le code où je planifie une tâche en utilisant java.util.timer. Je regardais autour de moi et j'ai vu ExecutorService faire la même chose. Donc, cette question ici, avez-vous utilisé Timer et ExecutorService pour planifier les tâches, quel est l'avantage d'une utilisation sur une autre?Java Timer vs ExecutorService?

Je voulais également vérifier si quelqu'un avait utilisé la classe Timer et a rencontré des problèmes que le ExecutorService a résolu pour eux.

+1

Et si vous avez besoin de quelque chose d'encore plus sophistiqué, consultez [quartz] (http://www.quartz-scheduler.org/). Il vous donne beaucoup plus de contrôle de travail, y compris la planification de type cron, la programmation en cluster, le contrôle individualisé des tâches (concepts tels qu'un seul jeu à la fois, dépendances, etc.). --Tim – Tim

Répondre

259

Selon Java Concurrency in Practice:

  • Timer peut être sensible aux changements de l'horloge système, ScheduledThreadPoolExecutor n'est pas.
  • Timer a un seul thread d'exécution, une tâche de longue durée peut donc retarder d'autres tâches. ScheduledThreadPoolExecutor peut être configuré avec n'importe quel nombre de threads. En outre, vous avez un contrôle total sur les threads créés, si vous le souhaitez (en fournissant ThreadFactory).
  • exceptions d'exécution lancées dans TimerTask tuer qu'un fil, ce qui rend Timer :-(mort ... à savoir les tâches planifiées ne fonctionnera plus. ScheduledThreadExecutor prises non seulement des exceptions d'exécution, mais il vous permet de les manipuler si vous voulez (en remplaçant afterExecute méthode de ThreadPoolExecutor). Tâche qui a jeté exception sera annulée, mais d'autres tâches continuera à fonctionner.

Si vous pouvez utiliser ScheduledThreadExecutor au lieu de Timer, faites-le.

une chose ... tandis que ScheduledThreadExecutor n'est pas disponible à La bibliothèque Java 1.4, il y a un Backport of JSR 166 (java.util.concurrent) to Java 1.2, 1.3, 1.4, qui a la classe ScheduledThreadExecutor.

20

ExecutorService est plus récent et plus général. Une minuterie est juste un fil qui exécute périodiquement des choses que vous avez prévu pour cela.

Un ExecutorService peut être un pool de fil, ou même se propager à travers d'autres systèmes dans un cluster et faire des choses comme unique exécution par lots, etc ...

Il suffit de regarder ce que chaque offre de décider.

56

S'il vous est accessible, il est difficile de penser à une raison et non à pour utiliser le framework d'exécution Java 5. Vocation:

ScheduledExecutorService ex = Executors.newSingleThreadScheduledExecutor(); 

vous donnera un ScheduledExecutorService avec des fonctionnalités similaires à Timer (il sera seul thread), mais dont l'accès peut être un peu plus évolutive (sous le capot, il utilise des structures concurrentes plutôt que la synchronisation complète avec la classe Timer).L'utilisation d'un ScheduledExecutorService vous donne également des avantages tels que:

  • Vous pouvez personnaliser le cas échéant (voir le newScheduledThreadPoolExecutor() ou la classe ScheduledThreadPoolExecutor)
  • Le « one off » les exécutions peuvent retourner des résultats

a propos des seules raisons pour coller à Timer je peux penser sont:

  • Il est disponible avant Java 5
  • Une classe similaire est prévue dans J2ME, ce qui pourrait rendre le portage de votre application plus facile (mais il ne serait pas très difficile d'ajouter une couche d'abstraction commune dans ce cas)
+0

Une autre raison d'utiliser 'TimerTask' peut être la disponibilité de la méthode' scheduledExecutionTime() 'qui ne semble pas avoir d'équivalent dans' ScheduledExecutorService'. –

+3

Une autre note: J'écris ce commentaire en 2k17, il n'y a plus de J2ME. c'est déjà mort. – msangel

+1

Java Timer-classe est merdique. – JohnyTex

5

Ma raison de préférer parfois minuterie sur Executors.newSingleThreadScheduledExecutor(), c'est que j'obtiens du code beaucoup plus propre quand j'ai besoin que le timer s'exécute sur les threads du démon.

comparer

private final ThreadFactory threadFactory = new ThreadFactory() { 
    public Thread newThread(Runnable r) { 
     Thread t = new Thread(r); 
     t.setDaemon(true); 
     return t; 
    } 
}; 
private final ScheduledExecutorService timer = Executors.newSingleThreadScheduledExecutor(threadFactory); 

avec

private final Timer timer = new Timer(true); 

Je le fais quand je ne ai pas besoin de la robustesse d'un ExecutorService.

2

De page de documentation Oralce sur ScheduledThreadPoolExecutor

A ThreadPoolExecutor qui peut en outre des commandes planning de après un délai donné, ou d'exécuter périodiquement. Cette classe est préférable à Timer lorsque plusieurs threads de travail sont nécessaires ou lorsque la flexibilité ou les capacités supplémentaires de ThreadPoolExecutor (que cette classe étend) sont requises.

ou ScheduledThreadPoolExecutor est un choix évident lorsque vous avez plusieurs threads de travail.

Plus de ExecutorService sur Timer

  1. Timer ne peuvent pas tirer profit des cœurs de processeur disponibles à la différence ExecutorService en particulier avec de multiples tâches à l'aide falvours de ExecutorService comme ForkJoinPool
  2. ExecutorService fournit des API colloborative si vous avez besoin coordiantion entre multple les tâches. Supposons que vous devez soumettre N nombre de tâches de travail et attendre la fin de chacune d'elles. Vous pouvez facilement y parvenir avec invokeAll API. Si vous voulez atteindre la même chose avec plusieurs tâches Timer, ce ne serait pas simple.
  3. ThreadPoolExecutor fournit une meilleure API pour la gestion du cycle de vie du fil.

    Les pools de threads traitent de deux problèmes différents: ils fournissent de meilleures performances lors de l'exécution un grand nombre de tâches asynchrones, grâce à la réduction par tâche invocation des frais généraux, et ils fournissent un moyen de délimitation et la gestion des ressources, y compris les discussions, consommé lors de l'exécution d'une collection de tâches. Chaque ThreadPoolExecutor maintient également quelques statistiques de base, telles que le nombre de tâches accomplies

    Peu d'avantages:

    a. Vous pouvez créer/gérer/contrôler le cycle de vie des threads & optimiser les frais généraux de création de threads

    b. Vous pouvez contrôler le traitement des tâches (Work Stealing, ForkJoinPool, invokeAll), etc.

    c. Vous pouvez surveiller la progression et la santé des threads

    d. Fournit un meilleur mécanisme de gestion des exceptions