In der Entwicklung benötigen wir häufig einige regelmäßige Operationen, z. B. alle paar Minuten eine bestimmte Operation durchführen. Zu diesem Zeitpunkt müssen wir einen Timer festlegen. Der bequemste und effizienteste Weg, es in Java zu implementieren, besteht darin, die Toolklasse von Java.util.timer zu verwenden und dann die Aufgabe von Java.util.TimerTask zu planen.
Timer ist ein Tool, mit dem es Aufgaben anordnet, die später in Hintergrund -Threads ausgeführt werden. Aufgaben können einmal ausgeführt oder wiederholt ausgeführt werden. Es ist eigentlich ein Thread, der die TimerTasks der Zeitplanung plant.
TimerTask ist eine abstrakte Klasse, deren Unterklassen von Timer als Aufgaben angeordnet sind, die ausgeführt oder wiederholt werden. Tatsächlich handelt es sich um eine Klasse mit einer Run -Methode, und der Code, der regelmäßig ausgeführt werden muss, wird in die Run -Methode -Körperschaft eingegeben.
Java startete den Timer-Klassen-Timer in JDK1.3 und entwickelte dann den Schedulethreadpoolexecutor, der Multi-Threading nach JDK1.5 unterstützt. Nach der Leistung des letzteren können wir den Timer vollständig ersetzen.
Vergleich zwischen Timer und Schedulethreadpoolexecutor:
1. Timer beginnt mit JDK1.3. Sein Prinzip ist es, ein Timertask -Array als Warteschlange zu verwenden, um dieser Warteschlange alle Zeitaufgaben hinzuzufügen. Dann starten Sie einen Thread. Wenn die Warteschlange leer ist, blockiert der Faden. Wenn sich in der Warteschlange Daten befinden
Unabhängig davon, ob die Zeit auf dem neuesten Stand ist, wird die Aufgabe ausgeführt, wenn die Laufzeit geringer oder gleich der aktuellen Zeit ist. Aufgrund seiner einzelnen Thread -Natur bringt es mehrere Probleme mit sich (detaillierter Code ist später):
Erstens, wenn die Aufgaben, die wir dem Timer hinzufügen, zeitaufwändig sind, da dieser Timer die Timeraufgaben auf einzelne Thread-sequentielle Weise ausführt, wirkt sich dies auf die rechtzeitige Ausführung nachfolgender Aufgaben aus.
Java -Code
// Beispiel für das Problem: m_timer.ScheduleatFixedrat (neue TaskUSelongTime (), 1000, 5000); m_timer.Scheduleatfixedrat (new tasknormal (), 5000, 3000); Auslaufergebnis: 14:44:29: Timer schläft 10 Sekunden 14:44:39: Timer schläft 14:44:39: Timer schläft 10 Sekunden 14:44:49: Aufgabe Normal ausgeführt 14:44:49: Aufgabe Normal ausgeführt 14:44:49: Aufgabe Normal ausgeführt 14:44:49: Aufgabe Normal ausgeführt 14:44: 449: Aufgabe Normal ausgeführt 14:49: 49: Aufgabe Normal ausgeführt 14:44:49: Aufgabe Normal ausgeführt 14:49:49: Aufgabe Normal ausgeführt 14:44:49: Aufgabe ausgeführt 14:49: Aufgabe Normale Aufgabe 14:44:49: Aufgabe ausgeführt. 14:44:49: Aufgabe Normal ausgeführt 14:44:49: Timer schläft 10 Sekunden Ergebnisanalyse: Die Aufgabe von Tasknormalen kann nicht alle 3 Sekunden garantiert werden. Es kann nur darauf warten, dass TaskUSelongTime nach Abschluss der TaskUSelongTime ausgeführt wird.
Zweitens fängt der Thread in Timer nur die InterruptedException -Ausnahme an. Wenn unsere benutzerdefinierte Timing -Aufgabe keine möglichen Ausnahmen erfasst und die Ausnahme ausgelöst wird, wird dies ausgelöst.
// Beispiel 2: m_timer.Schedule (neue TaskThrowException (), 1000); M_Timer.Schedule (New Tasknormal (), 2000); Run-Ergebnis: 14:47:37: Ausnahme von Ausnahme in Thread "Timer-0" java.lang.runtimexception bei Timer_test.TimerTest $ taskthrowException.run (timertest.java:85) bei Java.util.timerThread.mainloop (Timer.java:512) at timeThread (Mainloop (Timer.java:512)) ATIL. java.util.timerThread.run (timer.java:462) Ergebnisanalyse: Nach einer Ausnahme durch eine Aufgabe kann die nachfolgende Aufgabe nicht weiter ausgeführt werden.
Dadurch wird unser Timer -Thread gestoppt, so dass andere nachfolgende Aufgaben nicht ausgeführt werden können.
Drittens können mehrere Timing -Aufgaben, die gleichzeitig auftreten
// Analyse der drei Fragen: m_timer.Scheduleatfixedrat (neue TaskUSelongTime ("Timer1"), 1000, 15000); m_timer.ScheduleatFixedRate (neue TaskUSelongTime ("Timer2"), 1000, 15000); Auslaufergebnis: 14:50:16: Timer1 schläft 10 Sekunden 14:50:26: Timer2 schläft 10 Sekunden 14:50:36: Timer2 schläft 10 Sekunden Ergebnisanalyse: Meine Startzeit ist 1 Sekunde später, aber die Startzeit zwischen Timer1 und Timer2 ist offensichtlich inkonsistent inkonsistentCodebeispiel:
package timer_test;import java.text.SimpleDateFormat;import java.util.Date;import java.util.Timer;import java.util.TimerTask;public class TimerTest {private final Timer m_timer = new Timer();public static void main(String[] args) {new TimerTest().test();}public void test() {//A Beispiel des Problems: m_timer.ScheduleatFixedrat (new TaskUSelongTime (), 1000, 5000); // M_timer.Schedule (New Tasknormal (), 2000); // Beispiel 3: // m_timer.ScheduleatFixedrat (neue TaskUSelongTime ("Timer1"), 1000, 5000); // m_timer.ScheduleatFixedRate (neue TaskUSelongTime ("Timer2"), 1000, 5000);} private class TaskUSelongTime erweitert Timertask {private String m_taskName = "Timer"; publicUsUlongTime () {} public TaskUnname (String taskname) {m_tasknime = taskuselongtime (@String taskname) {m_tasknime {try {System.out.println(getCurrentTime()+": "+m_taskName+" is sleeping 10 seconds");Thread.sleep(10000);}catch (InterruptedException e) {}}}private class TaskNormal extends TimerTask {@Override public void run() {System.out.println(getCurrentTime()+": Task Normal ausgeführt ");}} private class TaskthrowException erweitert Timertask {@Override public void run () {System.out.println (GetCurrentTime ()+": Ausnahme werfen ").2.Schedulethreadpoolexecutor
Schedulethreadpoolexecutor begann mit JDK1.5 und wurde von Herrn Doula geschrieben. Es verwendet die clevere Kombination von ThreadPoolexecutor und DelayQueue, um die Implementierung des Multi-Thread-Timers zu vervollständigen und die oben genannten drei Defekte zu lösen, die durch einen einzelnen Timer verursacht werden.
Das Problem in Frage 1 ist, dass die nachfolgenden Aufgaben nicht rechtzeitig erledigt werden können, da einzelne Threads nacheinander ausführen. Wir sehen, dass Multi-Threading dieses Problem leicht lösen kann. Gleichzeitig haben wir festgestellt, dass die Ausführungszeit von TaskUSelongTime 10s beträgt (siehe den nachfolgenden Code). Wir haben das Aufgabenintervall von 5 Sekunden vorgenommen, aber aus dem Ergebnis stellten wir fest, dass unser Aufgabenausführungsintervall 10 Sekunden beträgt, sodass wir beurteilen können, dass Schedulethreadpoolexecutor in einem Thread-per-Task-Modus arbeitet.
// Problem 1: m_timer.ScheduleatFixedrat (neue TaskUSelongTime (), 1000, 5000, TimeUnit.Milliseconds); m_timer.ScheduleatFixedRate (New Tasknormal (), 1000, 5000, Timeunit.Milliseconds); Auslaufergebnis: 14:54:37: Aufgabe Normal ausgeführt 14:54:37: Timer schläft 10 Sekunden 14:54:42: Aufgabe Normal ausgeführt 14:54:47: Aufgabe Normal ausgeführt 14:54:47: Aufgabe Normal ausgeführt 14:54:47: Timer schläft 10 Sekunden 14:54:52: Aufgabe normal ausgeführt.
In Frage 2 stellten wir fest, dass die Ausführung der Aufgabe bei der Ausnahme der Ausnahme den Betrieb anderer Aufgaben nicht beeinflusst. Gleichzeitig stellten wir fest, dass unsere Ausnahme nicht im Laufergebnis geworfen wurde. Dies liegt daran, dass die Schedulethreadpoolexecutor -Klasse nach Ausführung der zeitgesteuerten Aufgabe ein geplanter Future -Run -Ergebnis zurückgibt. Unabhängig davon, ob das Ergebnis erfolgreich ist oder es Ausnahmen gibt, wird es hier gespeichert.
// Problem 2: m_timer.ScheduleatFixedrat (neue TaskThrowException (), 1000, 5000, TimeUnit.Milliseconds); m_timer.ScheduleatFixedRate (New Tasknormal (), 1000, 5000, Timeunit.Milliseconds); Auslaufergebnis: 14:58:36: Ausnahme werfen 14:58:36: Aufgabe Normal ausgeführt 14:58:41: Aufgabe Normal ausgeführt 14:58:46: Aufgabe normal ausgeführt 14:58:46: Aufgabe normal ausgeführt 14:58:46: Aufgabe Normal ausgeführt 14:58:51: Aufgabe Normal ausgeführt 14:58:56: 56: Aufgabe normal ausgeführt ausgeführt wurde ausgeführt ausgeführt ausgeführt ausgeführt ausgeführt ausgeführt ausgeführt ausgeführt ausgeführt wurde ausgeführt.
Frage 3 Da es Multi-Threaded ist, können wir sicherstellen, dass unsere Zeitaufgaben gleichzeitig ausgeführt werden können.
// Problem 3: m_timer.Scheduleatfixedrat (neue TaskUSelongTime ("Timer1"), 1000, 5000, TimeUnit.Milliseconds); m_timer.ScheduleatFixedRate (neue TaskUSelongTime ("Timer2"), 1000, 5000, TimeUnit.Milliseconds); Laufen Ergebnis: 15:01:12: Timer1 schläft 10 Sekunden 15:01:12: Timer2 schläft 10 Sekunden 15:01:22: Timer2 schläft 10 Sekunden 15:01:22: Timer2 schläft 10 Sekunden 15 Sekunden 15:01:22: Timer2 schläft 10 Sekunden. 15:01:22: Timer2 schläft 10 Sekunden 15:01:22: Timer2 schläft 10 Sekunden 15:01:22: Timer2 schläft 10 Sekunden 15:01:22: Timer2 schläft 10 Sekunden. 15:01:22: Timer2 schläft 10 Sekunden 15:01:22: Timer2 schläft 10 Sekunden 15:01:22: Timer2 schläft 10 Sekunden 15:01:22: Timer2 schläft 10 Sekunden 15 Sekunden 15:01:22: Timer2 schläft 10 Sekunden 15:01: Seconds Sekunden 15:01:32: Timer2 schläft 10 SekundenDetaillierter Code:
Package Timer_test; import java.text.SimpledateFormat; import Java.util.date; import Java.util.Concurrent.Callable; PlantedThreadpoolexecutor m_timer = new Schedulled threadpoolexecutor (10); public static void main (String [] args) {{planeLethreadpoolexecutortest timertest = new Planethreadpoolexexecutortest (); timerTest.Test (); oder // m_timer.ScheduleatFixedRate (New Tasknormal (), 1000, 5000, TimeUnit.Milliseconds); // Frage 2: // m_timer.Scheduleatfixedrat (neue TaskThrowException (), 1000, 5000, TimeUnit.Milliseconds); // m_timer.ScheduleatFixedRate (New Tasknormal (), 1000, 5000, TimeUnit.Milliseconds); // Problem 3: m_timer.Scheduleatfixedrat (neue TaskUSelongTime ("Timer1"), 1000, 5000, TimeUnit.Millisekunden); Runnable {private String m_taskName = "Timer"; private TaskUSelongTime () {} private TaskUSelongTime (String taskname) {m_taskname = taskname;} public void run () {try {system.out.out.println (GetCurrentTime ()+":"+m_taskname+ist 10 Sekunden). (InterruptedException e) {}} public Integer call () löst Ausnahme aus {run (); return 0;}}@unterdrückungswarnings ("unbenutzt") Private Class Tasknormale implements Callable <Integer>, Runnable {public Integer call () Ausnahme {run (); Aufgabe normal ausgeführt ");}}@unterdrückungswarnings (" unbenutzt ") Private Class TaskThrowException implementiert Callable <Integer>, Runnable {public Integer call () löst Ausnahme aus {System.out.println (getCurrenttime ()+: Ausnahme werfen"); OderZusammenfassen
In der oben genannten Art dreht sich alles um die kurze Diskussion dieses Artikels über die Entwicklungsgeschichte von Java -Timern, und ich hoffe, dass es für alle hilfreich sein wird. Interessierte Freunde können weiterhin auf diese Seite verweisen:
Java implementiert eine einfache Analyse von Timer -Code
Das Prinzip und die Umsetzung des Timer -Timer -Timers von Java Multithread
Code Beispiel für die Verwendung von Java -Timer -Timer
Wenn es Mängel gibt, hinterlassen Sie bitte eine Nachricht, um darauf hinzuweisen. Vielen Dank an Freunde für Ihre Unterstützung für diese Seite!