Java Threads und die Zeit

Guten Morgen meine IT-Kollegen,

gerade stieß ich wieder auf ein Problem, welches unter normalen Umständen nicht auftreten sollte: Die Uhrzeit des Hosts ändert sich. Dies sollte bei Programmen die keine Threads haben, oder Threads, die alle paar Stunden einmal ausgeführt werden sollen, in der Regel kein Problem sein. Bei Threads die wichtige Daten alle paar Minuten auswerten / verschieben / löschen sollen, kann dies aber unter Umständen zu dem Problem führen, dass der Thread erst bei der nächsten Uhrzeit ausgeführt wird (Thread.sleep(), Timer und der TimerTask sind hier so Kandidaten).

Zur Veranschaulichung folgende Situation die ich letztens hatte: Ein Programm verschiebt Daten alle X Sekunden (oder sobald eine Datei in ein C:\Pfad landet) auf einen UNC-Pfad. Jetzt wird die nächste Ausführung durch den Timer auf die aktuelle Zeit plus den eingestellten Delay gesetzt. Auf Grund eines Backup-Systems mit einer falschen Uhrzeit, wird die Zeit des Hosts mit der Zeit des Backup-Systems, ein eigenes System mit leider falsch eingestellter Uhrzeit welches von meinem Kollegen verwaltet wird, synchronisiert (sollte nicht passieren, aber das ist ein anderes Thema) und somit um 2 Stunden nachgestellt.

Der Thread wird wieder ausgeführt und setzt die Zeit wieder auf die veränderte aktuelle Zeit plus den vorher eingestellten Delay. Das Backup System wird anschließend fertig und die Zeit wird wieder auf die vorherige zurück gestellt. Jetzt hätten wir auf dem Host beispielsweise 10:00 Uhr, auf dem Backup-System 12:00 Uhr und der nächste Thread würde um 12:02 Uhr anfangen. In den zwei Stunden macht das Programm gar nichts, da der Thread geplant ist und so gesehen kein Fehler zum Auswerfen vorliegt.

So weit dazu.

Dies scheint vor allem an den von Java verwendeten Funktionen zu liegen. Allen voran die Funktion System.currentTimeMillis(). Man könnte nun eigene Klassen und Funktionen schreiben, die statt dieser die Funktion System.nanoTime() verwendet, aber dann müsste man die damit zusammenhängenden Funktionen auch neu schreiben und da diese leider meist private deklariert wurden die entsprechenden Klassen gleich mit dazu.

Sowas mache ich meist eher ungern 😉

Eine gute Möglichkeit für den Ersatz von java.util.Timer (oder entsprechender anderer Klasse) ist ein ScheduledThreadPoolExecutor. Dies könnte in Verwendung in etwa wie folgt aussehen:

Ist natürlich nur ein Beispiel. Man könnte unter anderem die return Werte von scheduleAtFixedRate() in einem Future Array speichern und dann abfragen, aber das gehört in einen anderen Beitrag 😉

Viel Spaß beim Programmieren

Lukas

Java: Probleme mit dem FTP

Guten Morgen meine Freunde der Nacht,

ich arbeite ja bekanntlich noch an meiner kleinen Toolbox. Heute bin ich auf ein weiteres Problem gestoßen auf das ich erst einmal testen darf: Manche Dateien werden per storeFile() verschoben, manche nicht. Hat möglicherweise mit der Aneinander-Reihung von Daten zu tun, aber das ist bis jetzt lediglich eine Vermutung. Ich lasse jetzt mal den Reply vom FTP-Server ausgeben und schaue mal, was hier falsch laufen könnte.

Außerdem habe ich einen (kleinen, aber miesen) Fehler behoben; wenn ich nach dem Upload die Daten lösche, sollte ich eventuell auch darauf prüfen, ob der Upload funktioniert hat, ansonsten werden die Daten einfach gelöscht und niemand hat sie mehr 😀

Update 20.05: Nachdem die Server ausgefallen sind, konnte ich erst einmal nicht an der Toolbox weiterarbeiten. Das Problem mit der storeFile()-Aneinanderreihung durch die Threads hat sich „gelöst“. Beim Upload wird jeweils geprüft ob der Nutzer angemeldet ist, was auch nötig ist, wenn lange Zeit nichts hoch-geladen wurde. Wenn allerdings mehrere Threads in der Überprüfung landen und einer sich schon angemeldet hat, können es die anderen Threads nicht mehr, da nur ein Nutzer vorhanden, und landen in einem „Socket write error“; zumindest meistens.

Ich habe hier einfach den Pool auf eins gesetzt. Dann gibt es nur einen Thread der einen Stack abarbeitet. Dadurch werden alle Dateien nach einander verschoben. Eine andere Möglichkeit kenne ich nicht und werde ich wohl erst einmal nicht benötigen. Bei Verschiebungen in einem normalen Dateisystem werden keine Anmeldungen benötigt und daher kann ich dort so viele Threads aufmachen wie ich Lust habe (zumindest in der Theorie).

Mal schauen welche Probleme mich noch erwarten 😉