# Thread sleep Bug



## thE_29 (16. Jul 2008)

Hohi!

Also wenn man ein Thread.sleep(10000) zB macht und während dem Sleep die Zeit zurückdreht, so wartet er nicht diese 10 Sekunden sondern bis die Zeit wirklich bei den 10 Sekunden vorbe ist...

Bsp.:


```
long timeStamp = System.currentTimeMillis();
    System.out.println("JETZT: " + new Date().toLocaleString());
    Thread.currentThread().sleep(10000);
    System.out.println("NACHHER: " + new Date().toLocaleString());
    System.out.println("DIFF: " + (System.currentTimeMillis() - timeStamp));
```

Ausgabe:


> JETZT: 16.07.2008 09:24:14
> 
> NACHHER: 16.07.2008 09:23:22
> 
> DIFF: -51379



Habe die Uhr einfach eine Minute zurückgedreht...

Wenn man die Uhr nach vorne stellt, spinnt das ganze noch mehr. Auf C Basis (also ein 1:1 gleiches programm in C) funktioniert aber wirklich wie es soll. Egal ob ich die Zeit verstelle!!

Weiß jemand wie man das Problem umgehen kann?! (Tritt laut meinen Entwicklern auch unter Linux auf)


----------



## byte (16. Jul 2008)

> wenn man ein Thread.sleep(10000) zB macht und während dem Sleep die Zeit zurückdreht, so wartet er nicht diese 10 Sekunden sondern bis die Zeit wirklich bei den 10 Sekunden vorbe ist...


Den Satz verstehe ich nicht. Wie lange schläft der Thread nun? Und wie hast Du das gemessen? System.currentTimeMillis() geht auf die Systemzeit. Wenn Du die verstellst, kannst Du damit wohl keine vernünftigen Zeitmessungen mehr machen.

Der Ausgabe zu urteilen scheint doch alles korrekt zu funktionieren. Die 2 Sek Differenz können Rundungsfehler sein und/oder durch das Verstellen der Uhr verursacht sein.


----------



## thE_29 (16. Jul 2008)

10 Sekunden sind 10 Sekunden, egal ob ich an der Zeit manipuliere.

Problem ist, das er nicht 10 Sekunden wartet, sondern 1 Minute und 10 Sekunden! Also solange bis die zurückgestellte Uhrzeit wieder passt.

Problem ist, wenn ich die Zeit um 1 Stunde zurücksetze. So wartet dieses Sleep nicht 10 Sekunden sondern 1 Stunde + 10 Sekunden!!


Nachtrag: OK, das C Sleep verhält sich genauso! Angeblich gehts mit usleep! Naja, gucken wir mal.


----------



## Kaini (16. Jul 2008)

Das geht nicht so einfach mit _System.currentTimeMillis()_

Wenn der Thread um 12:00:00 für 10 Minuten schlafen geht, und du stellst die Uhr eine Minute nach vor, muss 12:09:00 rauskommen. Dabei hat der Thread *10 Minuten* geschlafen!
Weil wenn du die Uhr nach vor stellst kannst du dir vorstellen, dass der Thread schon um 11:59:00 zum schlafen begonnen hat. (Und bis 12:09:00 sind das nunmal 10 Minuten).

Dazu folgender Test: Ich lasse 2 Uhren mitlaufen - meine Computer Uhr und eine echte Uhr. Die Computer Uhr verstelle ich, die echte nicht.

```
public static void main(String[] args) throws InterruptedException {
        long timeStamp = System.currentTimeMillis(); // PC=10:01 REAL=10:01
        System.out.println("JETZT: " + new Date().toLocaleString());
        Thread.sleep(1000 * 60 * 2); // Zeit zurück gestellt: PC=10:01 REAL=10:02
        System.out.println("NACHHER: " + new Date().toLocaleString()); // PC=10:02 REAL=10:03
        System.out.println("DIFF: " + (System.currentTimeMillis() - timeStamp));
    }
```
Du siehst es steht wirklich 2 Minuten still. Außer ich hab mich sehr grob verschaut


----------



## thE_29 (16. Jul 2008)

Also bei mir schläft der eindeutig länger als 10 Sekunden!
Probiers mit meinem Bsp!

Einfach 10 Sekunden schlafen lassen und die Uhr um 1 Minute zurückdrehen und du wirst sehen, das sind nie und nimmer 10 Sekunden was er da wartet!

Habe aber das gleiche Bsp jetzt unter Linux getestet und da funktioniert es..


----------



## The_S (16. Jul 2008)

@Kaini

dein Geschriebenes ist wirklich mehr als verwirrend - und wies weiterhelfen soll weiß ich auch nicht ???:L .


----------



## Kaini (16. Jul 2008)

Naja ob es helfen tut weiß ich nicht - aber es ist ein Beweis das er nicht recht hat.

Ich habe gerade in Java sleep für zwei Minuten gemacht - meine Uhr auf 9:08 zurückgestellt und er hat nur 2 Minuten geschlaften!

Edit: Ich verwende Gentoo Linux und JRE 1.6


----------



## thE_29 (16. Jul 2008)

So und um es jedem zu zeigen hier ein Video:
http://members.inode.at/j.taschek/sleep_bug.rar

Und wenn dadurch dass das Video ja schon mal länger als 10 Sekunden dauert, kann der Sleep kaum 10 Sekunden gehen!!

@Kaini: Unter Linux FUNKTIONIERT es nach meinen Tests ja auch!! Nur unter Windows nicht!!


----------



## kleiner_held (16. Jul 2008)

Grosse Teile der Implementierung von Thread werden auf native Methoden der JVM und des OS runtergebrochen.
Das Verhalten von sleep() unter solchen Randbedingungen ist also abhaengig von der JVM Version und dem Betriebssystem.


----------



## Kaini (16. Jul 2008)

> Grosse Teile der Implementierung von Thread werden auf native Methoden der JVM und des OS runtergebrochen.
> Das Verhalten von sleep() unter solchen Randbedingungen ist also abhaengig von der JVM Version und dem Betriebssystem.



Das ist aber schlecht - nicht das jetzt alle Java Programmierer beginnen ihre Programme für Windows anzupassen.



> Weiß jemand wie man das Problem umgehen kann?! (Tritt laut meinen Entwicklern *auch unter Linux auf*)


 ???:L


----------



## thE_29 (16. Jul 2008)

Tjo, ich habe mir schnell eine DLL gebastelt und ein C Sleep gemacht. Komme aber auf das gleiche Bullshitergebnis!

Komisch ist ja das angeblich (ich teste das gleich) auf einer Wincor Nixdorf Linux Umgebung (basierend auf Fedora Core 4) und Java 1.5.0_07-b03 dieser Fehler auch auftritt!!

@Kaini: Sie habe mir das nur so gesagt! Wie gesagt unter einer SuSE 8.0 und Java 1.3 konnte ich es nicht nachstellen. Teste es gerade auf dieser Maschine wo der Fehler sein soll!!


----------



## tfa (16. Jul 2008)

Bei welchem Anwendungsfall ändert sich die Systemzeit schlagartig? Eigentlich ist sowas immer böse.


----------



## thE_29 (16. Jul 2008)

Tjo, es geht darum das Kassen immer die Zeitabgleichen mit unseren BackOffice PCs und da kann es sein, das die Uhrzeit während dem Betrieb um 1 Stunde zurückgestellt wird (Sommerzeitumstellung). Und dann hängt das Programm EWIG (also + 1 Stunde) wegen einem 10 Sekunden sleep.


----------



## kleiner_held (16. Jul 2008)

Kaini hat gesagt.:
			
		

> Das ist aber schlecht - nicht das jetzt alle Java Programmierer beginnen ihre Programme für Windows anzupassen.


Hat aber den riesen Vorteil, dass die JVM Threads auf Betriebssystem Prozesse abbilden koennen und damit auch von Scheduler Optimierungen des OS profitieren koennen.

Wenn das Problem in diesem Fall wirklich ein Showstopper ist, wuerde ich mal auf http://bugs.sun.com/ recherchieren oder schauen ob sich andere Projekte (z.B.: Quartz) schon damit rumgeschlagen haben.


----------



## thE_29 (16. Jul 2008)

OMFG!
Die hatten wirklich recht! Unter diesen Bedingungen tritt dieser Fehler wirklich auf...


----------



## tfa (16. Jul 2008)

Eigentlich sollte sich bei Sommer-/Winterzeitumstellung nichts an der Systemzeit ändern. Unter Unix sind das die vergangenen Sekunden seit 1.1.1970 UTC, Sommerzeit (Zeitzonen überhaupt) sind dann ein Problem der Anzeige. So sollte es unter Linux funktionieren. Wie das bei Windows ist, weiß ich nicht.


----------



## thE_29 (16. Jul 2008)

Tjo, hier der Beweis:
http://members.inode.at/j.taschek/sleep_bug_linux.rar

Ich werde mal ne neuere JRE 5 testen gehen..


----------



## ipsi (16. Jul 2008)

also ich habs jetztmal probiert.

zur übersicht nochmal der code:

```
public static void main(String[] args) throws InterruptedException {
        long timeStamp = System.currentTimeMillis();
        System.out.println("JETZT: " + new Date().toLocaleString());
        Thread.sleep(1000 * 60 * 2);
        System.out.println("NACHHER: " + new Date().toLocaleString());
        System.out.println("DIFF: " + (System.currentTimeMillis() - timeStamp));
    }
```

das ergebniss:

compile:
run:
JETZT: 16.07.2008 10:28:21
NACHHER: 16.07.2008 09:30:18
DIFF: -3483225
ERSTELLEN ERFOLGREICH (Gesamtzeit: 0 Minuten 0 Sekunden)


----------



## ipsi (16. Jul 2008)

achja verwende grade XP mit javaversion 1.6.0_06-b02


----------



## thE_29 (16. Jul 2008)

Komisch unter XP verwende ich java 1.6.0_04-b12 mit Win XP SP2 und da gings nicht!
Ich teste gerade mal die neueste JRE 6 Version unter Linux da es mit der letzten JRE5 auch nicht ging!


----------



## Guest (16. Jul 2008)

so bin jetzt mal regestriert   

echt bisi komisch...
ich mein ich bin jetzt sicher kein programmier ass, aber...
tja bin grad bisi ratlos... :bahnhof:


----------



## thE_29 (16. Jul 2008)

Komisch ist, das es selbst mit der JDK 1.6.0_10 bei mir unter XP nicht funktioniert!

Hingegen mit der letzten JRE6 unter Linux gehts auch auf diesem Wincor Nixdorf System! Problem ist nur, das wir Wincor Nixdorf jetzt überzeugen müssen, eine neue JRE mitauszulieferen und Epson muss schauen ob deren SW auch mit der 1.6 Tip Top läuft.


----------



## ipsi (16. Jul 2008)

Anonymous hat gesagt.:
			
		

> so bin jetzt mal regestriert
> 
> echt bisi komisch...
> ich mein ich bin jetzt sicher kein programmier ass, aber...
> tja bin grad bisi ratlos... :bahnhof:



so war komischerweiße ned eingeloggt, war von mir.

hmm... vllt spuckt google was aus  :###


----------



## thE_29 (16. Jul 2008)

Naja, da man das anscheinend nicht wirklich umgehen kann (zumindest bei bestimmen Java Versionen) gibts da wohl keine Abhilfe. Man muss halt damit leben..


----------



## didjitalist (17. Jul 2008)

Sind die Scheduler davon auch betroffen? Thread#sleep ist wirklich sehr systemnah, evtl. sind die Scheduler anders implementiert.


----------



## thE_29 (17. Jul 2008)

Naja, ich weiß, dass das beim Windows Shutdown program (shutdown.exe) genauso auftritt.
Also wenn man zB einestellt fahre den PC in 30 Sekunden runter und man verstellt die Uhrzeit, dann hat man das gleiche Verhalten.


----------



## Kaini (17. Jul 2008)

Wow - wirklich? Naja da wird sich so mancher Admin freuen.

Gibt es dagegen einen Warkaround oder muss man sich da was anderes überlegen.


----------

