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 ce faire, par opposition à la création d'un nouveau thread qui a une boucle infinie avec sleep?

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 de temps que l'intervalle.

Veuillez commenter à ce sujet..

Mise à jour:
Récemment, j'ai trouvé une autre différence entre l'utilisation de la minuterie et celle du Thread.dormir(). Supposons que l'heure système actuelle soit 11h00. Si nous annulons l'heure système à 10h00 pour une raison quelconque, Le minuteur 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 obstacle. Cela peut être un principal décideur pour décider quoi utiliser entre ces deux.

Author: Keshav, 2009-09-21

7 answers

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
Author: 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
Author: 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 Thread/problème de sommeil résolu.

 4
Author: Qandeel, 2011-10-03 03:40:08

Il existe un argument crucial contre la gestion de cette tâche à l'aide de threads Java et de la méthode sleep. Vous utilisez while(true) pour rester indéfiniment dans la boucle et hiberner le thread en 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 compte pour vous, c'est-à-dire NewUploadServer.getInstance().checkAndUploadFiles(); en appelant la méthode run() de votre TimerTask tout en laissant d'autres threads utiliser les ressources entre-temps.

 3
Author: Boris Pavlović, 2012-03-08 08:17:15

Si vous thread get exception et est 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
Author: 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 30 minutes 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 s'exécute jamais car toutes les tâches ne sont jamais terminées. Je pense que la collecte des ordures s'exécuterait lorsqu'une minuterie est en veille, mais je ne le vois pas et selon la documentation, ce n'est pas le cas.

Je pense que la génération de nouveaux threads se termine et de permettre à la collecte des ordures.

Quelqu'un se il vous plaît me prouver le contraire, réécrire ce que j'ai hérité va être une douleur.

 1
Author: Ken, 2014-11-20 03:24:48

À Partir de la Timer documentation:

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

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

  • Timer utilise un seul thread d'arrière-plan qui est utilisé pour exécuter toutes les tâches du minuteur, séquentiellement. Les tâches doivent donc 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 tueront 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 supprimer toutes 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 utilisateur auront terminé leur exécution.

Minuterie 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 en sommeil ne peut pas l'être, il ne peut être interrompu.
  2. Une attente (et une notification) doit se produire dans un bloc synchronisé sur l'objet monitor alors que le sommeil n'est pas.
  3. Pendant que sleep ne libère pas le verrou, waiting libère le verrou pour l'objet wait est appelé.
 0
Author: i_am_zero, 2018-09-13 04:01:36