Minuteur & TimerTask rapport à Fil + sommeil en Java

J'ai trouvé des questions similaires posées ici mais il n'y avait pas de réponses à ma satisfaction. Donc reformuler la question à nouveau -

J'ai une tâche qui doit être faite sur une base périodique (disons des intervalles de 1 minute). Quel est l'avantage d'utiliser Timertask & Timer pour le faire par opposition à la création d'un nouveau thread qui a une boucle infinie avec le sommeil?

Extrait de Code utilisant timertask -

TimerTask uploadCheckerTimerTask = new TimerTask(){

 public void run() {
  NewUploadServer.getInstance().checkAndUploadFiles();
 }
};

Timer uploadCheckerTimer = new Timer(true);
uploadCheckerTimer.scheduleAtFixedRate(uploadCheckerTimerTask, 0, 60 * 1000);

Extrait de Code utilisant Thread et sleep -

Thread t = new Thread(){
 public void run() {
  while(true) {
   NewUploadServer.getInstance().checkAndUploadFiles();
   Thread.sleep(60 * 1000);
  }
 }
};
t.start();

Je n'ai vraiment pas à m'inquiéter si je manquer certains cycles si l'exécution de la logique prend plus que le temps d'intervalle.

Veuillez commenter ceci..

Mise à jour:
Récemment, j'ai trouvé une autre différence entre l'utilisation de la minuterie par rapport au Thread.dormir(). Supposons que l'heure actuelle du système est 11: 00AM. Si nous annulons l'heure du système à 10h00 pour une raison quelconque, la minuterie cessera d'exécuter la tâche jusqu'à ce qu'elle ait atteint 11h00, alors que Thread.la méthode sleep() continuerait à exécuter la tâche sans entrave. Cela peut être un important décideur de décider quoi utiliser entre ces deux.

97
demandé sur Keshav 2009-09-21 11:47:45

7 réponses

L'avantage de TimerTask est qu'il exprime beaucoup mieux votre intention (c'est-à-dire la lisibilité du code), et il a déjà la fonctionnalité cancel() implémentée.

Notez qu'il peut être écrit sous une forme plus courte ainsi que votre propre exemple:

Timer uploadCheckerTimer = new Timer(true);
uploadCheckerTimer.scheduleAtFixedRate(
    new TimerTask() {
      public void run() { NewUploadServer.getInstance().checkAndUploadFiles(); }
    }, 0, 60 * 1000);
64
répondu Zed 2013-10-04 19:15:40

Timer / TimerTask prend également en compte le temps d'exécution de votre tâche, ce sera donc un peu plus précis. Et il traite mieux les problèmes de multithreading(comme éviter les blocages, etc.). Et bien sûr, il est généralement préférable d'utiliser un code standard bien testé au lieu d'une solution maison.

12
répondu MartinStettner 2009-09-21 08:02:35

Je ne sais pas pourquoi mais un programme que j'écrivais utilisait des minuteries et sa taille de tas augmentait constamment, une fois que je l'ai changé en Problème de Thread/sleep résolu.

4
répondu Qandeel 2011-10-03 03:40:08

Il y a un argument crucial contre la gestion de cette tâche en utilisant des threads Java et la méthode sleep. Vous utilisez while(true) pour rester indéfiniment dans la boucle et hiberner le fil en le mettant en veille. Que faire si NewUploadServer.getInstance().checkAndUploadFiles(); prend des ressources synchronisées. D'autres threads ne pourront pas accéder à ces ressources, la famine peut se produire ce qui peut ralentir toute votre application. Ces types d'erreurs sont difficiles à diagnostiquer et c'est une bonne idée d'empêcher leur existence.

L'autre approche déclenche l'exécution du code qui vous importe, c'est-à-dire NewUploadServer.getInstance().checkAndUploadFiles(); en appelant la méthode run() de votre TimerTask tout en laissant d'autres threads utiliser les ressources en attendant.

3
répondu Boris Pavlović 2012-03-08 08:17:15

Si vous obtenez une exception et que vous êtes tué, c'est un problème. Mais TimerTask s'en occupera. Il s'exécutera indépendamment de l'échec de l'exécution précédente.

3
répondu Stack Popper 2014-02-06 19:45:48

Je pense que je comprends votre problème, je vois quelque chose de très similaire. J'ai des minuteries qui sont récurrentes, certaines toutes les minutes 30 et d'autres tous les deux jours. D'après ce que j'ai lu et les commentaires que je vois, il semble que la collecte des ordures ne fonctionnera jamais parce que toutes les tâches ne sont jamais terminées. Je pense que la collecte des ordures fonctionnerait quand une minuterie est en veille, mais je ne le vois pas et selon la documentation, Ce n'est pas le cas.

Je pense que le frai de nouveaux threads se termine et de permettre à la collecte des ordures.

Quelqu'un s'il te plaît prouve-moi que j'ai tort, réécrire ce que j'ai hérité va être une douleur.

1
répondu Ken 2014-11-20 03:24:48

À Partir de la Timer documentation:

Java 5.0 introduit le java.util.simultanées paquet et l'un des les utilitaires de concurrence y sont ScheduledThreadPoolExecutor qui est un pool de threads pour l'exécution répétée de tâches à un rythme donné ou retard. Il est effectivement un remplacement plus polyvalent pour la Combinaison Timer / TimerTask, car elle permet plusieurs threads de service, accepte différentes unités de temps et ne nécessite pas de sous-classe TimerTask (juste implémenter Runnable). Configuration De ScheduledThreadPoolExecutor avec un thread, il est équivalent à Timer.

, Donc Préférez ScheduledThreadExecutor au lieu de Timer:

  • Timer utilise un thread d'arrière - plan unique qui est utilisé pour exécuter toutes les tâches de la minuterie, séquentiellement. Ainsi, les tâches devraient se terminer rapidement sinon cela retardera l'exécution des tâches suivantes. Mais dans le cas de ScheduledThreadPoolExecutor, nous pouvons configurer n'importe quel nombre de threads et pouvons également avoir un contrôle total en fournissant ThreadFactory.
  • Timer peut être sensible à l'horloge système car il utilise la méthode Object.wait(long). Mais ScheduledThreadPoolExecutor ne l'est pas.
  • les exceptions d'exécution lancées dans TimerTask vont tuer ce thread particulier, rendant ainsi la minuterie morte où nous pouvons gérer cela dans ScheduledThreadPoolExecutor afin que les autres tâches ne soient pas impactées.
  • Timer fournit la méthode cancel pour terminer le minuteur et ignorer les tâches planifiées, mais elle n'interfère pas avec la tâche en cours d'exécution et la laisse se terminer. Mais si la minuterie est s'exécutant en tant que thread démon, que nous l'annulions ou non, il se terminera dès que tous les threads de l'utilisateur auront terminé leur exécution.

Minuteur vs Thread.sommeil

Minuterie rend l'utilisation de Object.wait et il est différent de Thread.sleep

  1. un thread en attente (wait) peut être notifié (en utilisant notify) par un autre thread mais un thread endormi ne peut pas l'être, il ne peut être interrompu.
  2. une attente (et notify) doit se produire dans un bloc synchronisé sur l'objet monitor alors que le sommeil ne fonctionne pas.
  3. pendant que le sommeil ne libère pas le verrou, waiting libère le verrou car l'objet wait est appelé.
0
répondu i_am_zero 2018-09-13 04:01:36