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 :
-
Timerpeut être sensible aux changements de l'horloge du système,ScheduledThreadPoolExecutorn'est pas. -
Timern'a qu'un seul thread d'exécution, de sorte que la tâche de longue durée peut retarder d'autres tâches.ScheduledThreadPoolExecutorpeut ê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
TimerTasktuer qu'un seul thread, donc de faire desTimermorte :-( ... c'est à dire les tâches planifiées ne marchera plus.ScheduledThreadExecutorne capte pas seulement les exceptions runtime, mais il vous permet de les gérer si vous le souhaitez (en remplaçantafterExecuteparThreadPoolExecutor). 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 laScheduledThreadPoolExecutorclasse) - 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
-
Timerne peut pas profiter des cœurs CPU disponibles contrairement àExecutorServicesurtout avec des tâches multiples utilisant des saveurs deExecutorServicecomme ForkJoinPool -
ExecutorServicefournit 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