Java Timer vs ExecutorService?
j'ai le code où je planifie une tâche en utilisant java.util.timer
. Je regardais autour et j'ai vu ExecutorService
peut faire la même chose. Alors cette question ici, Avez-vous utilisé Timer et ExecutorService
pour programmer des tâches, quel est l'avantage d'une utilisation par rapport à une autre?
voulait aussi vérifier si quelqu'un avait utilisé la classe Timer
et a rencontré des problèmes que le ExecutorService
résolu pour eux.
6 réponses
Selon Java Simultanéité dans la Pratique :
-
Timer
peut être sensible aux changements de l'horloge du système,ScheduledThreadPoolExecutor
n'est pas. -
Timer
n'a qu'un seul thread d'exécution, de sorte que la tâche de longue durée peut retarder d'autres tâches.ScheduledThreadPoolExecutor
peut être configuré avec n'importe quel nombre de threads. En outre, vous avez le contrôle total sur les threads créés, si vous voulez (en fournissantThreadFactory
). - Runtime exceptions levées dans
TimerTask
tuer qu'un seul thread, donc de faire desTimer
morte :-( ... c'est à dire les tâches planifiées ne marchera plus.ScheduledThreadExecutor
ne capte pas seulement les exceptions runtime, mais il vous permet de les gérer si vous le souhaitez (en remplaçantafterExecute
parThreadPoolExecutor
). Tâche qui a jeté l'exception sera annulée, mais d'autres tâches continueront à courir.
si vous pouvez utiliser ScheduledThreadExecutor
au lieu de Timer
, faites-le.
encore une chose... alors que ScheduledThreadExecutor
n'est 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 la classe ScheduledThreadExecutor
.
S'il est disponible pour vous, alors il est difficile de penser à une raison pas d'utiliser le cadre de L'exécuteur Java 5. Appelant:
ScheduledExecutorService ex = Executors.newSingleThreadScheduledExecutor();
vous donnera un ScheduledExecutorService
avec des fonctionnalités similaires à Timer
(c'est-à-dire qu'il sera monofiltre) mais dont l'accès peut être légèrement plus évolutif (sous la hotte, il utilise des structures concurrentes plutôt que la synchronisation complète comme avec la classe Timer
). Utilisant un ScheduledExecutorService
vous offre également des avantages tels que:
- vous pouvez le personnaliser si nécessaire (voir la
newScheduledThreadPoolExecutor()
ou laScheduledThreadPoolExecutor
classe) - Le "one off" exécutions peuvent renvoyer des résultats
au sujet des seules raisons de s'en tenir à Timer
je peux penser à:
- Il est disponible en pré Java 5
- une classe similaire est prévue dans J2ME, qui pourrait faire porter votre application plus facilement (mais il ne serait pas très difficile d'ajouter une couche commune d'abstraction dans ce cas)
ExecutorService est plus récent et plus général. Un minuteur est juste un fil qui exécute périodiquement des choses que vous avez prévu pour elle.
un Exécutorservice peut être un pool de threads, ou même s'étendre à d'autres systèmes d'un cluster et faire des choses comme l'exécution par lots, etc...
il suffit de regarder ce que chaque offre de décider.
Voici d'autres bonnes pratiques concernant l'utilisation des minuteries:
http://tech.puredanger.com/2008/09/22/timer-rules /
en général, J'utiliserais Timer pour des trucs rapides et sales et exécuteur pour un usage plus robuste.
ma raison de préférer parfois la minuterie aux exécuteurs.newSingleThreadScheduledExecutor () est que j'obtiens du code beaucoup plus propre quand j'ai besoin du timer pour exécuter sur les threads de démons.
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 fais cela quand je n'ai pas besoin de la robustesse d'un exécutorservice.
de la page de documentation D'Oracle sur ScheduledThreadPoolExecutor
A ThreadPoolExecutor qui peut programmer en outre des commandes à exécuter après un délai donné, ou à 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 requis.
ExecutorService/ThreadPoolExecutor
ou ScheduledThreadPoolExecutor
est le choix évident lorsque vous avez plusieurs threads de travail.
Pros ExecutorService
plus Timer
-
Timer
ne peut pas profiter des cœurs CPU disponibles contrairement àExecutorService
surtout avec des tâches multiples utilisant des saveurs deExecutorService
comme ForkJoinPool -
ExecutorService
fournit API collaborative si vous avez besoin de coordination entre plusieurs tâches. Supposons que vous devez soumettre un nombre N de travailleur tâches et d'attendre l'achèvement de tous. Vous pouvez facilement l'obtenir avec L'API invokeAll . Si vous voulez réaliser la même chose avec plusieurs tâchesTimer
, ce ne serait pas simple. -
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 offrent habituellement de meilleures performances lors de l'exécution d'un grand nombre de tâches asynchrones, en raison de la réduction de l'invocation par tâche au-dessus, et ils fournissent un moyen de limiter et de gérer les ressources, y compris les threads, consommées lors de l'exécution d'une série de tâches. Chaque Thèmeadpoolexecutor maintient également des statistiques de base, telles que le nombre de tâches accomplies
Few avantages:
A. 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 ( vol de travail, ForkJoinPool, invokeAll) etc.
C. Vous pouvez surveiller le progrès et la santé des fils
D. Offre un meilleur mécanisme de traitement des exceptions