{"id":598,"date":"2016-09-20T15:03:00","date_gmt":"2016-09-20T13:03:00","guid":{"rendered":"http:\/\/lukas.kurth.rocks\/blog\/?p=598"},"modified":"2016-09-20T15:09:36","modified_gmt":"2016-09-20T13:09:36","slug":"java-threads-und-die-zeit","status":"publish","type":"post","link":"https:\/\/lukas.kurth.rocks\/blog\/2016\/09\/20\/java-threads-und-die-zeit\/","title":{"rendered":"Java Threads und die Zeit"},"content":{"rendered":"<p>Guten Morgen meine IT-Kollegen,<\/p>\n<p style=\"text-align: justify;\">gerade stie\u00df ich wieder auf ein Problem, welches unter normalen Umst\u00e4nden nicht auftreten sollte: <strong>Die Uhrzeit des Hosts \u00e4ndert sich<\/strong>. Dies sollte\u00a0bei Programmen die keine Threads haben, oder Threads, die alle paar Stunden einmal ausgef\u00fchrt werden sollen, in der Regel kein Problem sein. Bei Threads die wichtige Daten alle paar Minuten auswerten \/ verschieben \/ l\u00f6schen sollen, kann dies aber unter Umst\u00e4nden zu dem Problem f\u00fchren, dass der Thread erst bei der n\u00e4chsten Uhrzeit ausgef\u00fchrt wird (<em>Thread.sleep(), Timer<\/em> und\u00a0der <em>TimerTask<\/em> sind hier so Kandidaten).<\/p>\n<p style=\"text-align: justify;\">Zur Veranschaulichung folgende Situation die ich letztens hatte: Ein Programm verschiebt Daten alle X\u00a0Sekunden (oder sobald eine Datei in ein C:\\Pfad landet) auf einen UNC-Pfad. Jetzt wird die n\u00e4chste Ausf\u00fchrung 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.<\/p>\n<p style=\"text-align: justify;\">Der Thread wird wieder ausgef\u00fchrt und setzt die Zeit wieder auf die ver\u00e4nderte aktuelle Zeit plus den vorher\u00a0eingestellten Delay. Das Backup System wird anschlie\u00dfend fertig und die Zeit wird wieder auf die vorherige zur\u00fcck gestellt. Jetzt h\u00e4tten wir auf dem Host beispielsweise 10:00 Uhr, auf dem Backup-System 12:00 Uhr und der n\u00e4chste Thread w\u00fcrde 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.<\/p>\n<p style=\"text-align: justify;\">So weit dazu.<\/p>\n<p style=\"text-align: justify;\">Dies scheint vor allem an den von Java verwendeten Funktionen zu liegen. Allen voran die Funktion <em>System.currentTimeMillis()<\/em>. Man k\u00f6nnte nun eigene Klassen und Funktionen\u00a0schreiben, die statt dieser die Funktion <strong><em>System.nanoTime()<\/em><\/strong> verwendet, aber dann m\u00fcsste man die damit zusammenh\u00e4ngenden Funktionen auch neu schreiben und da diese leider meist private deklariert wurden die entsprechenden Klassen gleich mit dazu.<\/p>\n<p style=\"text-align: justify;\">Sowas mache ich meist eher ungern \ud83d\ude09<\/p>\n<p style=\"text-align: justify;\">Eine gute M\u00f6glichkeit f\u00fcr den Ersatz von java.util.Timer (oder entsprechender anderer Klasse) ist ein ScheduledThreadPoolExecutor. Dies k\u00f6nnte in Verwendung in etwa wie folgt aussehen:<\/p>\n<pre class=\"toolbar:1 lang:java mark:3,11 decode:true \" title=\"ScheduledThreadPoolExecutor.something\">@Override\r\npublic void start() {\r\n    ScheduledThreadPoolExecutor scheduler = new ScheduledThreadPoolExecutor(1);\r\n    \r\n    ArrayList&lt;TimerTask&gt; tasks = new ArrayList&lt;&gt;();\r\n    tasks.add(new NetworkInterfaceTask(tools));\r\n    tasks.add(new InternetConnectionTask(tools));\r\n    tasks.add(new ClockTask(tools, masterTimestamp));\r\n    tasks.add(getReachableTask());\r\n    \r\n    scheduler.scheduleAtFixedRate(tasks.get(0), 5, 5, TimeUnit.MINUTES); \/\/ NETWORK\r\n    scheduler.scheduleAtFixedRate(tasks.get(1), 5, 5, TimeUnit.MINUTES); \/\/ INTERNET\r\n    scheduler.scheduleAtFixedRate(tasks.get(2), 2, 2, TimeUnit.SECONDS); \/\/ CLOCK\r\n    scheduler.scheduleAtFixedRate(tasks.get(3), 5, 5, TimeUnit.MINUTES); \/\/ REACH\r\n}<\/pre>\n<p style=\"text-align: justify;\">Ist nat\u00fcrlich nur ein Beispiel.\u00a0Man k\u00f6nnte unter anderem die return Werte von <em>scheduleAtFixedRate()<\/em> in einem Future Array speichern und dann abfragen, aber das geh\u00f6rt in einen anderen Beitrag \ud83d\ude09<\/p>\n<p>Viel Spa\u00df beim Programmieren<\/p>\n<p>Lukas<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Guten Morgen meine IT-Kollegen, gerade stie\u00df ich wieder auf ein Problem, welches unter normalen Umst\u00e4nden nicht auftreten sollte: Die Uhrzeit des Hosts \u00e4ndert sich. Dies sollte\u00a0bei Programmen die keine Threads haben, oder Threads, die alle paar Stunden einmal ausgef\u00fchrt werden sollen, in der Regel kein Problem sein. Bei Threads die wichtige Daten alle paar Minuten [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1,5,17,9,13],"tags":[34,349,70,345,347,350,116,348,154,346,343,342,354,344,208,209,353,351,352],"class_list":["post-598","post","type-post","status-publish","format-standard","hentry","category-allgemein","category-it","category-java","category-programmierung","category-tips","tag-backup","tag-currenttimemillis","tag-edt","tag-executor","tag-future","tag-host","tag-java","tag-nanotime","tag-pool","tag-scheduleatfixedrate","tag-scheduledthreadpoolexecutor","tag-scheduler","tag-sleep","tag-tasks","tag-threads","tag-timer","tag-uhrzeit","tag-unc","tag-versatz"],"_links":{"self":[{"href":"https:\/\/lukas.kurth.rocks\/blog\/wp-json\/wp\/v2\/posts\/598","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/lukas.kurth.rocks\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/lukas.kurth.rocks\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/lukas.kurth.rocks\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/lukas.kurth.rocks\/blog\/wp-json\/wp\/v2\/comments?post=598"}],"version-history":[{"count":5,"href":"https:\/\/lukas.kurth.rocks\/blog\/wp-json\/wp\/v2\/posts\/598\/revisions"}],"predecessor-version":[{"id":603,"href":"https:\/\/lukas.kurth.rocks\/blog\/wp-json\/wp\/v2\/posts\/598\/revisions\/603"}],"wp:attachment":[{"href":"https:\/\/lukas.kurth.rocks\/blog\/wp-json\/wp\/v2\/media?parent=598"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/lukas.kurth.rocks\/blog\/wp-json\/wp\/v2\/categories?post=598"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/lukas.kurth.rocks\/blog\/wp-json\/wp\/v2\/tags?post=598"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}