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 effectuée périodiquement (disons 1 minute d'intervalle). Quel est l'avantage d'utiliser Timertask & Timer pour ce faire par rapport à la création d'un nouveau thread qui a une boucle infinie avec 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 rate certains cycles si l'exécution de la logique prend plus que l'intervalle de temps.
Veuillez commenter ceci.
Mise à jour:
Récemment, j'ai trouvé une autre différence entre l'utilisation de Timer et Thread.sleep (). Supposons que l'heure système actuelle soit 11h00. Si nous annulons l'heure système à 10h00 pour une raison quelconque, The Timer arrêtera d'exécuter la tâche jusqu'à ce qu'elle atteigne 11h00, tandis que la méthode Thread.sleep () continuerait d'exécuter la tâche sans entrave. Cela peut être un décideur majeur pour décider quoi utiliser entre les deux.
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à implémenté la fonction cancel ().
Notez qu'il peut être rédigé dans une forme plus courte ainsi que votre propre exemple:
la source
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.
la source
Je ne sais pas pourquoi mais un programme que j'écrivais utilisait Timers et sa taille de tas augmentait constamment, une fois que je l'ai changé en problème Thread / sleep résolu.
la source
Si votre thread obtient une exception et est tué, c'est un problème. Mais TimerTask s'en chargera. Il fonctionnera indépendamment de l'échec de l'exécution précédente.
la source
De la
Timer
documentation :Alors préférez
ScheduledThreadExecutor
au lieu deTimer
:Timer
utilise un thread d'arrière-plan unique 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 ce cas,ScheduledThreadPoolExecutor
nous pouvons configurer n'importe quel nombre de threads et pouvons également avoir un contrôle total en fournissantThreadFactory
.Timer
peut être sensible à l'horloge système car il utilise laObject.wait(long)
méthode. MaisScheduledThreadPoolExecutor
non.ScheduledThreadPoolExecutor
afin que les autres tâches ne soient pas affectées.Timer
fournit unecancel
méthode pour terminer le minuteur et ignorer toutes les tâches planifiées, mais il n'interfère pas avec la tâche en cours d'exécution et ne la laisse pas se terminer. Mais si le minuteur fonctionne en tant que thread démon, que nous l'annulions ou non, il se terminera dès que tous les threads utilisateur auront fini de s'exécuter.Minuterie vs Thread.sleep
Timer utilise
Object.wait
et il est différent deThread.sleep
wait
thread en attente ( ) peut être notifié (en utilisantnotify
) par un autre thread mais un thread en veille ne peut pas l'être, il ne peut être interrompu.la source
Il y a un argument crucial contre la gestion de cette tâche à l'aide de threads et de
sleep
méthodes Java . Vous utilisezwhile(true)
pour rester indéfiniment dans la boucle et mettre en veille le thread en le mettant en veille. Que faire siNewUploadServer.getInstance().checkAndUploadFiles();
prend certaines ressources synchronisées. Les autres threads ne pourront pas accéder à ces ressources, une famine peut survenir, ce qui peut ralentir toute votre application. Ces types d'erreurs sont difficiles à diagnostiquer et c'est une bonne idée de prévenir leur existence.L'autre approche déclenche l'exécution du code qui vous tient à cœur, c'est
NewUploadServer.getInstance().checkAndUploadFiles();
à dire en appelant larun()
méthode de votreTimerTask
tout en laissant d'autres threads utiliser les ressources entre-temps.la source
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 le ramasse-miettes ne fonctionnera jamais car toutes les tâches ne sont jamais terminées. Je pense que le ramasse-miettes s'exécuterait quand un minuteur est en veille, mais je ne le vois pas et selon la documentation, il ne le fait pas.
Je pense que la création de nouveaux threads se termine et permet le ramassage des ordures.
Quelqu'un s'il vous plaît me prouver le contraire, réécrire ce que j'ai hérité va être une douleur.
la source