En développement, nous avons souvent besoin de quelques opérations périodiques, comme effectuer une certaine opération toutes les quelques minutes. Pour le moment, nous devons définir une minuterie. La façon la plus pratique et la plus efficace de la mettre en œuvre en Java est d'utiliser la classe d'outils java.util.timer, puis de planifier la tâche java.util.timertask.
Timer est un outil qui l'utilise pour organiser des tâches qui seront exécutées dans des threads d'arrière-plan plus tard. Les tâches peuvent être exécutées une fois, ou elles peuvent être exécutées à plusieurs reprises. Il s'agit en fait d'un fil qui planifie les Timetasks appartenant à la planification chronométrée.
TIMERTASK est une classe abstraite dont les sous-classes sont organisées par minuterie comme des tâches qui sont exécutées ou répétées. En fait, c'est une classe avec une méthode d'exécution, et le code qui doit être exécuté régulièrement est placé dans le corps de la méthode d'exécution.
Java a lancé le temporisateur de la classe TIMER dans JDK1.3, puis Doulea a récemment développé le scheduletheadpoolExecutor qui prend en charge le multi-threading après JDK1.5. À en juger par les performances de ce dernier, nous pouvons envisager de remplacer complètement la minuterie.
Comparaison entre la minuterie et ScheduleThreadpoolExecutor:
1. La minuterie commence par JDK1.3. Son principe consiste à utiliser un tableau Timeratask comme file d'attente pour ajouter toutes les tâches de synchronisation à cette file d'attente. Puis démarrez un fil. Lorsque la file d'attente est vide, le fil se bloque. Lorsqu'il y a des données dans la file d'attente, le thread supprimera une time pour juger
Que l'heure soit à jour, la tâche commence à fonctionner si le temps d'exécution est inférieur ou égal à l'heure actuelle. En raison de sa nature de thread unique, il apporte plusieurs problèmes (le code détaillé est ultérieur):
Premièrement, lorsque les tâches que nous ajoutons à la minuterie prennent du temps, car ce temporisateur exécute les tâches de minuterie d'une manière séquentielle de thread unique, elle affectera l'exécution opportune des tâches suivantes.
Code java
// Exemple du problème: m_timer.scheduleatFixeDrate (new taskUSELongtime (), 1000, 5000); m_timer.scheduleatFixeDrate (new taskNormal (), 5000, 3000); Résultat en cours: 14:44:29: le temporisateur dort 10 secondes 14:44:39: le temporisateur dort 14:44:39: La minuterie dort 10 secondes 14:44:49: Tâche normale exécutée 14:44:49: Tâche normale exécutée 14:44:49: Tâche exécutée Tâche exécutée 14:4:49: Tâche normale exécutée 14:44:49: 14:44:49: Tâche normale exécutée 14:44:49: Le temporisateur dort 10 secondes Analyse des résultats: La tâche TaskNormal ne peut pas être garantie d'exécuter une fois toutes les 3 secondes, il ne peut qu'attendre que TaskUselongtime soit exécuté après sa fin.
Deuxièmement, le fil dans la minuterie n'attrapera que l'exception InterruptedException, donc si notre tâche de synchronisation personnalisée n'attrape pas des exceptions possibles et ne fait pas l'exception, l'exception,
// Exemple 2: m_timer.schedule (new TaskThrowException (), 1000); m_timer.schedule (new TaskNormal (), 2000); Résultat de l'exécution: 14:47:37: Jetez l'exception de l'exception dans le thread "Timer-0" java.lang.runtimeException sur timer_test.Timerst $ taskthrowException.run (Timestrest.java:85) sur java.util.timerthread.mainloop (timer.java:512) att java.util.timerthread.run (timer.java:462) Analyse des résultats: Une fois une exception lancée par une tâche, la tâche tasknormale suivante ne peut pas continuer à s'exécuter.
Cela entraînera l'arrêt de notre fil de minuterie, de sorte que d'autres tâches suivantes ne peuvent pas être exécutées.
Troisièmement, il ne peut pas gérer plusieurs tâches de synchronisation qui se produisent simultanément
// Analyse des trois questions: m_timer.scheduleatFixeDrate (new TaskUSElongtime ("TIMER1"), 1000, 15000); m_timer.scheduleAtFixeDrate (new TaskUselongtime ("TIMER2"), 1000, 15000); Résultat de course: 14:50:16: TIMER1 dort 10 secondes 14:50:26: Timer2 dort 10 secondes 14:50:36: Timer2 est de 10 secondes Analyse des résultats: mon temps de démarrage est de 1 seconde plus tard, mais le temps de démarrage entre TIMER1 et TIMER2 est évidemment inconsistantExemple de code:
package TIMER_TEST; IMPORT Java.Text.SimpledateFormat; import java.util.date; import java.util.timer; import java.util.timertask; public class TimerSest {private final timer m_timer = new timer (); public static void main (string [] args) {new timestrest (). du problème: m_timer.scheduleatFixeDrate (new TaskUselongtime (), 1000, 5000); m_timer.scheduleatfixeDrate (new taskNormal (), 5000, 3000); // Exemple 2: // m_timer.schedule (new taskthrowException (), 1000); // m_timer.schedule (new TaskNormal (), 2000); // Exemple 3: // m_timer.scheduleatFixeDrate (new taskUSELongtime ("TIMER1"), 1000, 5000); // m_timer.scheduleAtFixeDrate (new TaskUselongtime ("TIMER2"), 1000, 5000);} classe privée TaskUselongtime étend Timertask {private String M_TaskName = "TIMER"; public TaskUselongtime () {} public TaskUselongtime (String TaskName) {m_taskname = taskname; {try {System.out.println (getCurrentTime () + ":" + m_taskname + "est endormi 10 secondes"); thread.sleep (10000);} catch (interruptedException e) {}}} classe privée TaskNormal étend Timemertask {@Override Public Void run () {System.out.out.PrintLn (GetCurrenttime () + "Tank Normal exécuté ");}} classe privée TaskThrowException étend Timertask {@Override public void run () {System.out.println (getCurrentTime () +": Throw Exception "); Throw New RuntimeException ();}} private GetCurrentTime () {return new SimpletEformat (" hh: mm: ss ").2.SchedulethReadpoolExecutor
ScheduleThreadpoolExecutor a commencé avec JDK1.5 et a été écrit par M. Doulea. Il utilise la combinaison intelligente de ThreadpoolExecutor et delayQueue pour terminer la mise en œuvre de la minuterie multithread, résolvant les trois défauts ci-dessus causés par un seul thread dans la minuterie.
Le problème de la question 1 est que les tâches suivantes ne peuvent pas être terminées à temps car les threads uniques s'exécutent séquentiellement. Nous voyons que le multi-lancement peut facilement résoudre ce problème. Dans le même temps, nous avons remarqué que le temps d'exécution de TaskUSELongtime est de 10s (veuillez consulter le code suivant). Nous avons chronométré l'intervalle de tâche de 5 secondes, mais d'après le résultat, nous avons constaté que notre intervalle d'exécution de tâche est de 10 secondes, nous pouvons donc juger que ScheduleTheReadPoolExecutor fonctionne en mode par lait par tâche.
// Problème 1: m_timer.scheduleAtFixeDrate (new TaskUSELongtime (), 1000, 5000, timeunit.milliseconds); m_timer.scheduleatFixeDrate (new taskNormal (), 1000, 5000, timeunit.milliseconds); Résultat de l'exécution: 14:54:37: Tâche normale exécutée 14:54:37: Timer dort 10 secondes 14:54:42: Tâche normale exécutée 14:54:47: Tâche normale exécutée 14:54:47: Tâche normale exécutée 14:54:47: Timer dort 10 secondes 14:54:52: Tâche normale exécutée exécutée exécutée exécutée exécutée
Dans la question 2, nous avons constaté que lorsque l'exception est lancée, l'exécution de la tâche n'affecte pas le fonctionnement d'autres tâches. Dans le même temps, nous avons constaté que notre exception n'était pas jetée dans le résultat de la course. En effet, la classe ScheduleThreadPoolExecutor renverra un résultat d'exécution de FUTURE planifié après l'exécution de la tâche chronométrée. Que le résultat soit réussi ou qu'il y a des exceptions, elle sera enregistrée ici.
// Problème 2: m_timer.scheduleAtFixeDrate (new TaskThrowException (), 1000, 5000, timeunit.milliseconds); m_timer.scheduleatFixeDrate (new taskNormal (), 1000, 5000, timeunit.milliseconds); Running result: 14:58:36: Throw exception 14:58:36: Task Normal executed 14:58:41: Task Normal executed 14:58:46: Task Normal executed 14:58:46: Task Normal executed 14:58:46: Task Normal executed 14:58:51: Task Normal executed 14:58:56: Task Normal executed
Question 3 Puisqu'il est multi-thread, nous pouvons nous assurer que nos tâches de synchronisation peuvent être exécutées en même temps.
// Problème 3: m_timer.scheduleAtFixeDrate (new TaskUselongtime ("TIMER1"), 1000, 5000, timeunit.milliseconds); m_timer.scheduleAtFixeDrate (new TaskUSElongtime ("TIMER2"), 1000, 5000, timeunit.milliseconds); Résultat de course: 15:01:12: Timer1 dort 10 secondes 15:01:12: Timer2 dort 10 secondes 15:01:22: Timer2 est dort 10 secondes 15:01:22: Timer2 est dort 10 secondes 15:01:22: Timer2 est dort 10 secondes 15:01:22: Timer2 est endormi 10 secondes 15:01:22: TIMER2 est 10 secondes. 15:01:22: TIMER2 dort 10 secondes 15:01:22: Timer2 dort 10 secondes 15:01:22: Timer2 est dort 10 secondes 15:01:22: Timer2 est endormi 10 secondes 15:01:22: TIMER2 est dort 10 secondes 15:01:22: Timer2 est endormi 10 secondes 15:01:22: TIMER2 est Dormers 15:01:22: Timer2 dort 10 secondes 15:01:22: Timer2 dort 10 secondes 15:01:22: Timer2 est dort 10 secondes 15:01:22: TIMER2 est dort 10 secondes 15:01:22: Timer2 est dort 10 secondes 15:01: Seconds 15:01:22: Timer1 est slee secondes 15:01:32: Timer2 dort 10 secondesCode détaillé:
Package TIMER_TEST; Importer java.text.simpledateformat; import java.util.date; import java.util.concurrent.callable; import java.util.concurrent.scheduledThereadpoolExecutor; import java.util.concurrent.TimeUnit; public classe publique scheduleThreadpoolExExExExExEx ScheduledThreadpoolExecutor m_timer = new scheduledTheredpoolExecutor (10); public static void main (String [] args) {schedulefeadpoolExeCutOrest Timestrest = new scheduleTheadpoolExeCutOrest (); timeTest.Test (); try {thread.Sleep (100000);} capture (interrupt. {TimerTest.shutdown ();}} public void shutdown () {m_timer.shutdown ();} public void test () {// Question 1: // m_timer.scheduleatFixeDrate (new taskuselongtime (), 1000, 5000, timeunit.MilleseConds); // m_timer.scheduleatFixeDrate (new taskNormal (), 1000, 5000, timeunit.milliseconds); // Question 2: // m_timer.scheduleatFixeDrate (new TaskThrowException (), 1000, 5000, timeunit.milliseconds); // m_timer.scheduleatFixeDrate (new taskNormal (), 1000, 5000, timeunit.milliseconds); // Problème 3: m_timer.scheduleatFixeDrate (new taskuselongtime ("timer1"), 1000, 5000, timeunit.millisecondes); m_timer.scheduleatfixedrate (new taskuselongtime ("timer2"), 1000, 5000, timeunit.Milleseconds);} Callable <Integer>, Runnable {private String m_taskName = "TIMER"; private taskuselongtime () {} private taskuselongtime (String taskName) {m_taskName = taskName;} public void run () {try {System.out.println (getCurrenttime () + ":" + m_taskname + ". secondes "); thread.sleep (10000);} catch (InterruptedException e) {}} public Integer Call () lève une exception {run (); return 0;}} @ suppresswarnings (" inutilisé ") Classe privée TaskNormal implémente Callable <Neger>, Runnable {public Integer Call () Throws exception {run (); Retour 0;} Gens run () {System.out.println (getCurrentTime () + ": Throw Exception"); Throw new RuntimeException ();}} private String getCurrentTime () {return new SimpledateFormat ("HH: mm: ss"). format (new Date ());}}Résumer
Ce qui précède concerne la brève discussion de cet article sur l'histoire du développement des minuteries Java, et j'espère qu'elle sera utile à tout le monde. Les amis intéressés peuvent continuer à se référer à ce site:
Java implémente un code de code de minuterie simple
Le principe et la mise en œuvre de la minuterie de la minuterie multithread Java
Exemple de code de la façon d'utiliser la minuterie de la minuterie Java
S'il y a des lacunes, veuillez laisser un message pour le signaler. Merci vos amis pour votre soutien pour ce site!