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.

232
demandé sur mtsz 2009-01-04 00:54:27

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 fournissant ThreadFactory ).
  • Runtime exceptions levées dans TimerTask tuer qu'un seul thread, donc de faire des Timer 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çant afterExecute par ThreadPoolExecutor ). 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 .

273
répondu Peter Štibraný 2015-09-15 22:09:27

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 la ScheduledThreadPoolExecutor 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)
57
répondu Neil Coffey 2014-04-30 16:34:31

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.

22
répondu Dustin 2009-01-03 22:06:24

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.

14
répondu Alex Miller 2009-01-04 00:34:18

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.

5
répondu Siamaster 2015-04-12 20:52:27

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

  1. Timer ne peut pas profiter des cœurs CPU disponibles contrairement à ExecutorService surtout avec des tâches multiples utilisant des saveurs de ExecutorService comme ForkJoinPool
  2. 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â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 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

3
répondu Ravindra babu 2018-07-18 09:47:47