it-swarm.com.de

Timer und TimerTask vs Thread + schlafen in Java

Ich habe ähnliche Fragen hier gestellt, aber zu meiner Zufriedenheit gab es keine Antworten. Also formuliere die Frage noch einmal

Ich habe eine Aufgabe, die regelmäßig erledigt werden muss (sagen wir alle 1 Minute). Welchen Vorteil bietet Timertask & Timer dazu, anstatt einen neuen Thread zu erstellen, der eine Endlosschleife mit Sleep hat.

Code-Snippet mit Zeittask

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 vermisse, wenn die Ausführung der Logik mehr als die Intervallzeit benötigt.

Bitte kommentieren Sie dies ..

Aktualisieren:
Kürzlich fand ich einen anderen Unterschied zwischen der Verwendung von Timer und Thread.sleep (). Angenommen, die aktuelle Systemzeit ist 11:00 Uhr. Wenn wir die Systemzeit aus irgendeinem Grund auf 10:00 Uhr zurücksetzen, stoppt The Timer die Ausführung der Aufgabe bis zum Erreichen von 11:00 Uhr, während die Methode Thread.sleep () die Aufgabe ohne Behinderung fortsetzt. Dies kann ein wichtiger Entscheider bei der Entscheidung sein, was zwischen diesen beiden verwendet werden soll.

101
Keshav

Der Vorteil von TimerTask ist, dass es Ihre Absicht viel besser zum Ausdruck bringt (d. H. Die Lesbarkeit von Code) und bereits die Funktion cancel () implementiert ist.

Beachten Sie, dass es sowohl in kürzerer Form als auch in Ihrem eigenen Beispiel geschrieben werden kann:

Timer uploadCheckerTimer = new Timer(true);
uploadCheckerTimer.scheduleAtFixedRate(
    new TimerTask() {
      public void run() { NewUploadServer.getInstance().checkAndUploadFiles(); }
    }, 0, 60 * 1000);
65
Zed

Timer/TimerTask berücksichtigt auch die Ausführungszeit Ihrer Aufgabe, sodass sie etwas genauer ist. Außerdem werden Multithreading-Probleme (z. B. Vermeidung von Deadlocks usw.) besser behandelt. Und natürlich ist es in der Regel besser, statt einer hausgemachten Lösung einen gut getesteten Standardcode zu verwenden.

13
MartinStettner

Ich weiß nicht warum, aber ein Programm, das ich schrieb, verwendete Timers und seine Heap-Größe nahm ständig zu, sobald ich es in ein Thread-/Schlaf-Problem geändert hatte.

5
Qandeel

Wenn der Thread eine Ausnahme erhält und beendet wird, stellt dies ein Problem dar. TimerTask kümmert sich darum. Es wird unabhängig vom Fehler des vorherigen Laufs ausgeführt.

4
Stack Popper

Es gibt ein entscheidendes Argument gegen die Verwaltung dieser Aufgabe mit Java-Threads und der sleep-Methode. Sie verwenden while(true), um unbegrenzt in der Schleife zu bleiben und den Thread in den Ruhezustand zu versetzen, indem Sie den Ruhezustand aktivieren. Was ist, wenn NewUploadServer.getInstance().checkAndUploadFiles(); einige synchronisierte Ressourcen in Anspruch nimmt. Andere Threads können nicht auf diese Ressourcen zugreifen. Es kann zu Verhungern kommen, was die 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 Codes aus, der für Sie von Bedeutung ist, d. H. NewUploadServer.getInstance().checkAndUploadFiles();, indem Sie die run()-Methode Ihrer TimerTask aufrufen, während andere Threads in der Zwischenzeit die Ressourcen verwenden.

3
Boris Pavlović

Aus der TimerDokumentation :

Java 5.0 führte das Java.util.concurrent-Paket und eines der .__ ein. Nebenläuferdienstprogramme sind darin der ScheduledThreadPoolExecutor, der ist ein Thread-Pool für die wiederholte Ausführung von Aufgaben mit einer bestimmten Rate oder verzögern. Es ist effektiv ein vielseitiger Ersatz für die Timer/TimerTask-Kombination, da sie mehrere Service-Threads zulässt, akzeptiert verschiedene Zeiteinheiten und erfordert keine Unterklasse von TimerTask (Einfach Runnable implementieren). ScheduledThreadPoolExecutor .__ konfigurieren. mit einem Thread entspricht es dem Timer.

Also lieber ScheduledThreadExecutor statt Timer:

  • Timer verwendet einen einzelnen Hintergrundthread, der zum sequenziellen Ausführen aller Tasks des Timers verwendet wird. Aufgaben sollten daher schnell abgeschlossen sein, andernfalls werden nachfolgende Aufgaben verzögert. Im Fall von ScheduledThreadPoolExecutor können wir jedoch eine beliebige Anzahl von Threads konfigurieren und haben auch die vollständige Kontrolle, indem wir ThreadFactory bereitstellen.
  • Timer kann empfindlich auf die Systemuhr reagieren, da sie die Object.wait(long)-Methode verwendet. ScheduledThreadPoolExecutor ist es nicht.
  • Laufzeit-Ausnahmen, die in TimerTask ausgelöst werden, beenden den betreffenden Thread und machen den Timer daher inaktiv, da wir dies in ScheduledThreadPoolExecutor behandeln können, so dass die anderen Aufgaben nicht betroffen sind.
  • Die Variable Timer bietet die Methode cancel, um den Timer zu beenden und geplante Tasks zu verwerfen. Dies wirkt sich jedoch nicht auf die aktuell ausgeführte Task aus. Wenn der Timer jedoch als Daemon-Thread ausgeführt wird, wird er abgebrochen, sobald alle Benutzer-Threads ausgeführt wurden.

Timer vs Thread.sleep

Der Timer verwendet Object.wait und unterscheidet sich von Thread.sleep

  1. Ein wartender Thread (wait) kann (mit notify) von einem anderen Thread benachrichtigt werden, ein ruhender Thread kann jedoch nicht unterbrochen werden. Er kann nur unterbrochen werden.
  2. Ein Warten (und eine Benachrichtigung) muss in einem auf das Monitorobjekt synchronisierten Block erfolgen, der Ruhezustand jedoch nicht.
  3. Wenn der Schlafmodus die Sperre nicht aufhebt, gibt das Warten die Sperre für das Objekt frei, auf das gewartet wird.
1
i_am_zero

Ich glaube, ich verstehe dein Problem, ich sehe etwas sehr ähnliches. Ich habe wiederkehrende Timer, alle 30 Minuten und 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 nie abgeschlossen sind. Ich würde denken, dass die Speicherbereinigung laufen würde, wenn sich ein Timer im Schlaf befindet, aber ich sehe es nicht und der Dokumentation zufolge nicht.

Ich denke, dass das Auftauchen neuer Threads abgeschlossen ist und die Müllsammlung erlaubt.

Bitte beweisen Sie mir, dass jemand falsch ist. Was ich geerbt habe, wird ein Schmerz sein.

1
Ken