J'ai du code où je planifie une tâche en utilisant java.util.Timer
. Je regardais autour de moi et j'ai vu que l' ExecutorService
on pouvait faire de même. Donc, cette question ici, avez-vous utilisé Timer
et ExecutorService
pour planifier des tâches, quel est l'avantage d'une utilisation par rapport à une autre?
Je voulais également vérifier si quelqu'un avait utilisé la Timer
classe et rencontré des problèmes qui les avaient ExecutorService
résolus.
Réponses:
Selon Java Concurrency en pratique :
Timer
peut être sensible aux changements d'horloge du système,ScheduledThreadPoolExecutor
n'est-ce pas.Timer
n'a qu'un seul thread d'exécution, donc une tâche de longue durée peut retarder d'autres tâches.ScheduledThreadPoolExecutor
peut être configuré avec un nombre illimité de threads. De plus, vous avez un contrôle total sur les threads créés, si vous le souhaitez (en fournissantThreadFactory
).TimerTask
kills qu'un fil, ce qui rendTimer
mort :-( ... à savoir les tâches planifiées ne fonctionneront plus.ScheduledThreadExecutor
Non seulement les captures exceptions en mode Process, mais il vous permet de les manipuler si vous voulez (en remplaçant laafterExecute
méthode à partirThreadPoolExecutor
). Tâche qui Cette exception sera annulée, mais d'autres tâches continueront de s'exécuter.Si vous pouvez utiliser à la
ScheduledThreadExecutor
place deTimer
, faites-le.Encore
ScheduledThreadExecutor
une chose ... bien qu'il ne soit pas disponible dans la bibliothèque Java 1.4, il existe un backport de JSR 166 (java.util.concurrent
) vers Java 1.2, 1.3, 1.4 , qui a laScheduledThreadExecutor
classe.la source
S'il est à votre disposition, il est difficile de penser à une raison pour ne pas utiliser le framework exécuteur Java 5. Appel:
vous donnera un
ScheduledExecutorService
avec des fonctionnalités similaires àTimer
(c'est- à -dire qu'il sera monothread) mais dont l'accès peut être légèrement plus évolutif (sous le capot, il utilise des structures simultanées plutôt qu'une synchronisation complète comme avec laTimer
classe). L'utilisation d'unScheduledExecutorService
offre également des avantages tels que:newScheduledThreadPoolExecutor()
ou leScheduledThreadPoolExecutor
cours)Les seules raisons pour lesquelles
Timer
je pense sont les suivantes:la source
TimerTask
peut être la disponibilité d'unescheduledExecutionTime()
méthode qui ne semble pas avoir d'équivalentScheduledExecutorService
.ExecutorService est plus récent et plus général. Une minuterie n'est qu'un fil qui exécute périodiquement des éléments que vous avez planifiés pour elle.
Un ExecutorService peut être un pool de threads, ou même réparti sur d'autres systèmes dans un cluster et faire des choses comme une exécution par lots ponctuelle, etc.
Il suffit de regarder ce que chacun propose pour décider.
la source
Voici quelques bonnes pratiques supplémentaires concernant l'utilisation de la minuterie:
http://tech.puredanger.com/2008/09/22/timer-rules/
En général, j'utiliserais Timer pour des trucs rapides et sales et Executor pour une utilisation plus robuste.
la source
Depuis la page de documentation Oracle sur ScheduledThreadPoolExecutor
ExecutorService/ThreadPoolExecutor
ouScheduledThreadPoolExecutor
est un choix évident lorsque vous avez plusieurs threads de travail.Pour de
ExecutorService
plusTimer
Timer
ne peut pas tirer parti des cœurs de processeur disponibles contrairement à enExecutorService
particulier avec plusieurs tâches utilisant des saveursExecutorService
comme ForkJoinPoolExecutorService
fournit une API collaborative si vous avez besoin d'une coordination entre plusieurs tâches. Supposons que vous devez soumettre N nombre de tâches de travail et attendre la fin de chacune d'entre elles. Vous pouvez facilement y parvenir avec invokeAll API. Si vous voulez obtenir le même résultat avec plusieursTimer
tâches, ce ne serait pas simple.ThreadPoolExecutor fournit une meilleure API pour la gestion du cycle de vie des threads.
Peu d'avantages:
une. Vous pouvez créer / gérer / contrôler le cycle de vie des threads et 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
ré. Fournit un meilleur mécanisme de gestion des exceptions
la source
La raison pour laquelle je préfère parfois Timer à Executors.newSingleThreadScheduledExecutor () est que j'obtiens un code beaucoup plus propre lorsque j'ai besoin que le timer s'exécute sur les threads du démon.
comparer
avec
Je le fais quand je n'ai pas besoin de la robustesse d'un service d'exécution.
la source