Ich fand hier ähnliche Fragen, aber es gab keine Antworten zu meiner Zufriedenheit. Also die Frage noch einmal umformulieren -
Ich habe eine Aufgabe, die regelmäßig erledigt werden muss (z. B. Intervalle von 1 Minute). Was ist der Vorteil der Verwendung von Timertask & Timer, anstatt einen neuen Thread zu erstellen, der eine Endlosschleife mit Schlaf hat?
Code-Snippet mit Timertask-
TimerTask uploadCheckerTimerTask = new TimerTask(){
public void run() {
NewUploadServer.getInstance().checkAndUploadFiles();
}
};
Timer uploadCheckerTimer = new Timer(true);
uploadCheckerTimer.scheduleAtFixedRate(uploadCheckerTimerTask, 0, 60 * 1000);
Code-Snippet mit Thread und sleep-
Thread t = new Thread(){
public void run() {
while(true) {
NewUploadServer.getInstance().checkAndUploadFiles();
Thread.sleep(60 * 1000);
}
}
};
t.start();
Ich muss mir wirklich keine Sorgen machen, wenn ich bestimmte Zyklen verpasse, wenn die Ausführung der Logik länger als die Intervallzeit dauert.
Bitte kommentieren Sie dies ..
Update:
Kürzlich habe ich einen weiteren Unterschied zwischen der Verwendung von Timer und Thread.sleep () festgestellt. Angenommen, die aktuelle Systemzeit ist 11:00 Uhr. Wenn wir die Systemzeit aus irgendeinem Grund auf 10:00 Uhr zurücksetzen, stoppt der Timer die Ausführung der Aufgabe, bis sie 11:00 Uhr erreicht hat, während die Thread.sleep () -Methode die Ausführung der Aufgabe ungehindert fortsetzt. Dies kann ein wichtiger Entscheidungsträger bei der Entscheidung sein, was zwischen diesen beiden verwendet werden soll.
Antworten:
Der Vorteil von TimerTask besteht darin, dass es Ihre Absicht viel besser ausdrückt (dh die Lesbarkeit des Codes) und die Funktion cancel () bereits implementiert ist.
Beachten Sie, dass es sowohl in kürzerer Form als auch in Ihrem eigenen Beispiel geschrieben werden kann:
quelle
Timer / TimerTask berücksichtigt auch die Ausführungszeit Ihrer Aufgabe, sodass sie etwas genauer ist. Und es behandelt besser Multithreading-Probleme (wie das Vermeiden von Deadlocks usw.). Und natürlich ist es normalerweise besser, gut getesteten Standardcode anstelle einer hausgemachten Lösung zu verwenden.
quelle
Ich weiß nicht warum, aber ein Programm, das ich schrieb, verwendete Timer und seine Heap-Größe nahm ständig zu, nachdem ich es in Thread / Schlaf-Problem geändert hatte.
quelle
Wenn Ihr Thread eine Ausnahme erhält und getötet wird, ist dies ein Problem. Aber TimerTask wird sich darum kümmern. Es wird unabhängig von einem Fehler im vorherigen Lauf ausgeführt.
quelle
Aus der
Timer
Dokumentation :Also
ScheduledThreadExecutor
lieber alsTimer
:Timer
Verwendet einen einzelnen Hintergrundthread, mit dem alle Aufgaben des Timers nacheinander ausgeführt werden. Aufgaben sollten also schnell erledigt werden, da sonst die Ausführung nachfolgender Aufgaben verzögert wird. Im Falle von könnenScheduledThreadPoolExecutor
wir jedoch eine beliebige Anzahl von Threads konfigurieren und durch Bereitstellung auch die volle Kontrolle habenThreadFactory
.Timer
kann empfindlich auf die Systemuhr reagieren, da sie eineObject.wait(long)
Methode verwendet. IstScheduledThreadPoolExecutor
aber nicht.ScheduledThreadPoolExecutor
damit die anderen Aufgaben nicht beeinträchtigt werden.Timer
Bietet einecancel
Methode zum Beenden des Timers und zum Verwerfen geplanter Aufgaben, beeinträchtigt jedoch nicht die aktuell ausgeführte Aufgabe und lässt sie beenden. Wenn der Timer jedoch als Daemon-Thread ausgeführt wird, wird er beendet, sobald alle Benutzer-Threads ausgeführt wurden, unabhängig davon, ob wir ihn abbrechen oder nicht.Timer vs Thread.sleep
Timer nutzt
Object.wait
und unterscheidet sich vonThread.sleep
wait
) Thread kannnotify
von einem anderen Thread benachrichtigt (verwendet ) werden, ein schlafender Thread jedoch nicht, er kann nur unterbrochen werden.quelle
Es gibt ein entscheidendes Argument gegen die Verwaltung dieser Aufgabe mithilfe von Java-Threads und
sleep
-Methoden. Sie verwendenwhile(true)
, um unbegrenzt in der Schleife zu bleiben und den Thread in den Ruhezustand zu versetzen, indem Sie ihn in den Ruhezustand versetzen. Was ist, wennNewUploadServer.getInstance().checkAndUploadFiles();
einige synchronisierte Ressourcen belegt werden ? Andere Threads können nicht auf diese Ressourcen zugreifen. Es kann zu einem Hunger kommen, der Ihre gesamte Anwendung verlangsamen kann. Diese Art von Fehlern ist schwer zu diagnostizieren und es ist eine gute Idee, ihre Existenz zu verhindern.Der andere Ansatz löst die Ausführung des für Sie wichtigen Codes aus, dh
NewUploadServer.getInstance().checkAndUploadFiles();
indem Sie dierun()
Methode von aufrufen,TimerTask
während andere Threads in der Zwischenzeit die Ressourcen verwenden.quelle
Ich glaube, ich verstehe Ihr Problem, ich sehe etwas sehr Ähnliches. Ich habe wiederkehrende Timer, einige alle 30 Minuten und einige alle paar Tage. Nach dem, was ich gelesen habe und den Kommentaren, die ich sehe, sieht es so aus, als würde die Garbage Collection niemals ausgeführt, da alle Aufgaben niemals abgeschlossen sind. Ich würde denken, dass die Speicherbereinigung ausgeführt wird, wenn ein Timer im Ruhezustand ist, aber ich sehe es nicht und laut Dokumentation nicht.
Ich denke, dass das Laichen neuer Threads abgeschlossen ist und die Speicherbereinigung ermöglicht.
Jemand, bitte beweise mir das Gegenteil. Das Umschreiben von dem, was ich geerbt habe, wird ein Schmerz sein.
quelle