web-dev-qa-db-fra.com

Java Timer vs ExecutorService?

J'ai un code où je programme une tâche en utilisant Java.util.timer. Je cherchais autour de moi et j'ai vu ExecutorService en faire autant. 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?

Voulait également vérifier si quelqu'un avait utilisé la classe Timer et rencontré des problèmes que le ExecutorService résolvait pour lui.

252
kal

Selon Java Concurrency in Practice :

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

Une dernière chose ... Bien que ScheduledThreadExecutor ne soit pas disponible dans la bibliothèque Java 1.4, il existe un --- (portage de JSR 166 (Java.util.concurrent) À Java 1.2, 1.3, 1.4 , qui a la classe ScheduledThreadExecutor.

295
Peter Štibraný

S'il est disponible, il est alors difficile de trouver une raison pas d'utiliser le framework = Java 5). Appeler:

ScheduledExecutorService ex = Executors.newSingleThreadScheduledExecutor();

vous donnera un ScheduledExecutorService avec une fonctionnalité similaire à Timer (c’est-à-dire qu’il sera mono-thread), mais dont l’accès sera peut-être légèrement plus évolutif (sous le capot, il utilise des structures concurrentes plutôt que la synchronisation complète comme avec la classe Timer). L'utilisation de ScheduledExecutorService vous donne également des avantages tels que:

  • Vous pouvez le personnaliser si besoin est (voir la classe newScheduledThreadPoolExecutor() ou la classe ScheduledThreadPoolExecutor)
  • Les exécutions uniques peuvent renvoyer des résultats

Les seules raisons pour lesquelles je reste fidèle à Timer sont les suivantes:

  • Il est disponible pre Java 5
  • Une classe similaire est fournie dans J2ME, ce qui pourrait faciliter le portage de votre application (mais il ne serait pas très difficile d'ajouter une couche d'abstraction commune dans ce cas)
61
Neil Coffey

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

Un ExecutorService peut être un pool de threads, voire même être réparti sur d'autres systèmes d'un cluster et effectuer des opérations telles que l'exécution par lots ponctuelle, etc.

Il suffit de regarder ce que chacun propose de décider.

22
Dustin

Voici quelques bonnes pratiques supplémentaires concernant l'utilisation du minuteur:

http://tech.puredanger.com/2008/09/22/timer-rules/

En général, j'utiliserais Timer pour les trucs rapides et sales et Executor pour une utilisation plus robuste.

15
Alex Miller

Depuis la page de documentation Oracle sur ScheduledThreadPoolExecutor

Un ThreadPoolExecutor pouvant en outre planifier l'exécution de commandes après un délai donné ou 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 (auquel cette classe est étendue) sont nécessaires.

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

Les avantages de ExecutorService sur Timer

  1. Timer ne peut tirer parti des cœurs de processeur disponibles contrairement à ExecutorService, en particulier avec plusieurs tâches utilisant des variantes de ExecutorService comme ForkJoinPool
  2. ExecutorService fournit une API collaborative si vous avez besoin d'une coordination entre plusieurs tâches. Supposons que vous deviez soumettre un nombre N de tâches de travail et attendre qu'elles soient toutes terminées. Vous pouvez facilement y parvenir avec invokeAll API. Si vous voulez obtenir le même résultat avec plusieurs tâches Timer, ce ne serait pas simple.
  3. ThreadPoolExecutor fournit une meilleure API pour la gestion du cycle de vie des threads.

    Les pools de threads traitent deux problèmes différents: ils offrent généralement de meilleures performances lors de l'exécution d'un grand nombre de tâches asynchrones, en raison de la réduction de la charge d'appel par tâche, et ils permettent de lier et de gérer les ressources, y compris les threads, utilisées lors de l'exécution d'une collection de fichiers. les tâches. Chaque ThreadPoolExecutor gère également des statistiques de base, telles que le nombre de tâches terminées.

    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 thread

    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

6
Ravindra babu

La raison pour laquelle je préfère parfois préférer Timer à Executors.

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 n'ai pas besoin de la robustesse d'un service d'exécution.

5
Siamaster