Question

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

J'ai une tâche qui doit être fait sur une base périodique (disons intervalles 1 minute). Quel est l'avantage d'utiliser TimerTask & Timer pour le faire plutôt que de créer un nouveau thread qui a une boucle infinie avec le sommeil?

Extrait de code en 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 à l'aide de cette discussion et le sommeil -

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

Je n'ai vraiment pas à vous inquiéter si je manque certains cycles si l'exécution de la logique prend plus l'intervalle de temps.

S'il vous plaît commenter ce ..

Mise à jour:
Récemment, je trouve une autre différence entre l'utilisation de la minuterie par rapport Thread.sleep (). Supposons que le temps système actuel est 11:00. Si nous Rollback l'heure du système à 10h00 pour une raison quelconque, la minuterie ARRÊTER exécution de la tâche jusqu'à ce qu'il ait atteint 11:00, alors que la méthode Thread.sleep () continuerait d'exécuter la tâche sans entrave. Cela peut être un décideur important pour décider ce qu'il faut utiliser entre ces deux.

Était-ce utile?

La solution

L'avantage de TimerTask est qu'il exprime votre intention beaucoup mieux (à savoir la lisibilité du code), et il a déjà la fonction d'annulation () mis en œuvre.

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);

Autres conseils

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

Je ne sais pas pourquoi, mais un programme que j'écrivais utilisais Timers et sa taille de tas est en constante augmentation, une fois que je l'ai changé Enfilez / problème de sommeil résolu.

Si vous enfilez obtenir exception et se fasse tuer, c'est un problème. Mais TimerTask prendra soin. Il fonctionnera indépendamment de l'échec dans l'exécution précédente.

Il y a un argument essentiel contre la gestion de cette tâche à l'aide des threads Java et la méthode de sleep. Vous utilisez while(true) rester indéfiniment dans la boucle et mise en veille prolongée le fil en mettant à dormir. Que faire si NewUploadServer.getInstance().checkAndUploadFiles(); prend des ressources synchronisées. D'autres sujets ne pourront pas avoir accès à ces ressources, la famine peut se produire qui peut ralentir votre application entière. Ces types d'erreurs sont difficiles à diagnostiquer et il est une bonne idée pour éviter leur existance.

L'autre aproche déclenche l'exécution du code qui compte pour vous, à savoir NewUploadServer.getInstance().checkAndUploadFiles(); en appelant la méthode de run() de votre TimerTask tout en laissant d'autres threads en utilisant les ressources entre-temps.

De la Timer documentation :

  

Java 5.0 introduit le paquet java.util.concurrent et l'un des   utilitaires de simultanéité est dans celle-ci le ScheduledThreadPoolExecutor qui   est un pool de threads pour les tâches d'exécution à plusieurs reprises à un taux donné ou   retard. Il est effectivement un remplacement plus polyvalent pour la   combinaison Timer / TimerTask, car il permet des fils de services multiples,   accepte différentes unités de temps, et ne nécessite pas subclassing TimerTask   (Mettre en œuvre juste Runnable). Configuration ScheduledThreadPoolExecutor   avec un fil en fait équivalent à la minuterie.

Préférez ScheduledThreadExecutor au lieu de Timer:

  • Timer utilise fil d'arrière-plan unique qui est utilisé pour exécuter toutes les tâches de la minuterie, de façon séquentielle. Ainsi, les tâches doivent remplir rapidement sinon il va retarder l'exécution des tâches suivantes. Mais en cas de ScheduledThreadPoolExecutor nous pouvons configurer un nombre de threads et peut également avoir un contrôle complet en fournissant ThreadFactory.
  • Timer peut être sensible à l'horloge du système car il rend l'utilisation de la méthode de Object.wait(long). Mais ScheduledThreadPoolExecutor n'est pas.
  • Exceptions d'exécution lancées dans TimerTask tueront ce fil particulier, rendant ainsi la minuterie mort alors que nous pouvons gérer que ScheduledThreadPoolExecutor afin que les autres tâches ne sont pas concernés.
  • Timer fournit la méthode cancel de mettre fin à la minuterie et éliminer toutes les tâches planifiées, mais il ne gêne pas la tâche en cours d'exécution et laissez-le terminer. Mais si la minuterie est en cours d'exécution en tant que fils de démon alors si nous annulons ou non, il prendra fin dès que tous les fils de l'utilisateur sont finis d'exécution.

minuterie vs Thread.sleep

minuterie utilise Object.wait et il est différent de Thread.sleep

  1. Une attente (wait) fil peut être notifié (en utilisant notify) par un autre thread mais on ne peut pas dormir être, il ne peut être interrompue.
  2. Une attente (et aviser) doivent se produire dans un bloc synchronisé sur l'objet de l'écran alors que le sommeil ne fonctionne pas.
  3. Pendant le sommeil ne libère pas le verrou, l'attente va libérer le verrou pour l'attente d'objet est appelé.

Je pense que je comprends votre question, je vois quelque chose de très similaire. J'ai minuteries qui sont récurrents, quelques toutes les 30 minutes et quelques tous les deux jours. D'après ce que je lis et les commentaires que je vois, il semble que la collecte des ordures ne sera jamais exécutée car toutes les tâches ne sont jamais complètes. Je pense que la collecte des ordures serait exécuté quand une minuterie est en sommeil, mais je ne suis pas le voir et selon la documentation, il ne fonctionne pas.

Je pense que de nouvelles discussions fraie complète et permettre la collecte des ordures.

Quelqu'un s'il vous plaît me prouver, réécrire ce que je hérité va être une douleur.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top