Workaround für Thread.sleep()-Bug

Status
Nicht offen für weitere Antworten.

0xdeadbeef

Top Contributor
Ich poste das mal hier, weil ich denke, daß man kleine Werte für Thread.sleep() am ehesten bei Spielen benutzt...


Bekanntlich gibt es unter WinXP (u.ä.) einen Bug bei der Implementierung von Thread.sleep(), der dazu führt, daß man bei sehr kleinen Parameterwerten nicht nur unplausible Ergebnisse bekommt, sondern im schlimmsten Fall sogar die Systemzeit verstellen kann (weil die Systemuhr während er Programmausführung deutlich schneller läuft).
Das wurde vor langer Zeit mal diskutiert und ich habe damals als Workaround Sleep-Zeiten von unter 20ms verhindert, was auch ganz gut geklappt hat, aber auf schwachen Systemen halt eine CPU-Last von 100% verursachen kann.

Wie es der Zufall so will, bin ich heute zufällig über einen Workaround im Java Bugtracker gestolpert und wollte Euch nicht dumm sterben lassen, falls er hier noch nicht bekannt ist:

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6435126

Im Kern startet man einen Daemon-Thread, in dem man ein "Thread.sleep(Integer.MAX_VALUE)" aufruft.
Das führt anscheinend dazu, daß systemweit (!) auf eine Timerauflösung von 1ms (statt 10ms) umgestellt wird und man somit auch Sleep-Werte unter 10ms benutzen kann.
Weil die systemweite Timerauflösung sich nach der höchsten Anforderung der laufenden Prozesse richtet, kann es durchaus auch sein, daß bereits eine andere Anwendung die hohe Auflösung angefordert hat. Das erklärt vermutlich auch, warum die Sleep-Probleme nicht auf jedem Rechner aufgetreten sind (das mit dem Verstellen der Systemzeit hat aber vermutlich noch einen komplexeren Hintergrund).

Nebenbei: dem Bugtracker-Eintrag kann man auch entnehmen, daß es schon lange einen Schalter "ForceTimeHighResolution" für diesen Zweck gibt, der allerdings von Anfang an falsch implementiert war und man es für zu riskant hielt, die Funktionsweise des Schalters zu korrigieren, weil ja bislang alle damit zufrieden waren ;)

Leider kann ich den Workaround nicht wirklich testen, weil mein Rechner laut Perfmon bereits mit hoher Timerauflösung läuft. Falls jemand noch einen Rechner hat, auf dem das nicht der Fall ist (wie man es testet, ist ebenfalls im Bugtracker beschrieben), würde ich mich über eine Rückmeldung freuen, ob dieser Workaround tatsächlich funktioniert. Inbesondere würde ich natürlich auch gerne wissen, ob dieser Workaround das Verstellen der Systemzeit auf den dafür anfälligen Rechnern verhindert. Mein eigener (Firmen)-Testrechner ist leider nicht mehr existent.
 
S

SlaterB

Gast
was es nicht alles gibt..

bei mir jedenfalls keine Änderung,
bei
Code:
public class Test {

	public static void main(String[] args) throws Exception {
		trick17();
		Thread.sleep(500);
		long time = System.currentTimeMillis();
		for (int i = 0; i < 40; i++) {
			Thread.sleep(3);
			long newTime = System.currentTimeMillis();
			System.out.println("Time: " + (newTime - time));
			time = newTime;

		}
	}

	static void trick17() {
		new Thread() {
			{
				this.setDaemon(true);
				this.start();
			}

			public void run() {
				while (true) {
					try {
						Thread.sleep(Integer.MAX_VALUE);
					} catch (InterruptedException ex) {
						ex.printStackTrace();
					}
				}
			}
		};
	}

}
kommt mit oder ohne Trick 17 das typische
Time: 47
Time: 16
Time: 0
Time: 15
Time: 0
Time: 0
Time: 16
Time: 0
Time: 0
Time: 16
Time: 0
Time: 46
Time: 0
Time: 0
Time: 0
Time: 16
Time: 0
Time: 0
Time: 0
Time: 16
Time: 0
Time: 0
Time: 0
Time: 15
Time: 0
Time: 0
Time: 0
Time: 16
Time: 0
Time: 0
Time: 16
Time: 0
Time: 0
Time: 15
Time: 0
Time: 0
Time: 0
Time: 16
Time: 0
Time: 0
raus
 

Wildcard

Top Contributor
Beim Testen kann ich leider nicht helfen, ich habe kein Windows System, aber... wow.
Sehr interessant fand ich das hier:
at the start of the application create and start a daemon Thread that simply sleeps for a very long time (that isn't a multiple of 10ms) as this will set the timer period to be 1ms for the duration of that sleep
Warum wird die Auflösung nur dann erhöht, wenn der Prozess so lange schläft, das die Auflösung völlig egal ist (mal abgesehen von der seltsamen x*10 Einschränkung)? :lol:

Danke für diese Kuriosität :lol:
 

0xdeadbeef

Top Contributor
@SlaterB:
Ich fürchte, daß alleine die Aufrufe von "System.out.println" diese Messung unbrauchbar machen. Es wäre sinnvoller, eine Statistik zu machen und erst am Ende auszugeben.
Falls die Statistik genauso weit streut: hast Du mal mit Perfmon geschaut, ob Du eher 100+ oder 1000+ Interrupts pro Sekunde hast, während das Programm (nicht) läuft? Dazu müßte allerdings die Schleife etwas großzügiger dimensioniert sein.

@Wildcard: das "endlose" sleep muß man wohl nicht verstehen.
 
S

SlaterB

Gast
wie kann man da einen Einfuss von System.out.println vermuten,
was veranlasst dich dazu?
große Zeitsprünge wie die 46 in der Mitte könnte man ja damit zu erschlagen versuchen,
aber wenn so regelmäßig "0,0, typischer Zeitsprung von ~16" kommt,
dann ist das doch ein glasklares Spiel


hier nochmal mit StringBuilder und mehr sleep()
Code:
					StringBuilder b = new StringBuilder();
					long time = System.currentTimeMillis();
					for (int i = 0; i < 40; i++) {
						Thread.sleep(40);
						long newTime = System.currentTimeMillis();
						b.append("\nTime: ");
						b.append(newTime - time);
						time = newTime;

					}
					System.out.println(b);

Time: 46
Time: 32
Time: 47
Time: 31
Time: 47
Time: 47
Time: 31
Time: 47
Time: 31
Time: 47
Time: 31
Time: 47
Time: 47
Time: 31
Time: 47
Time: 31
Time: 47
Time: 31
Time: 47
Time: 31
Time: 47
Time: 47
Time: 31
Time: 47
Time: 32
Time: 46
Time: 32
Time: 47
Time: 46
Time: 32
Time: 47
Time: 31
Time: 47
Time: 31
Time: 47
Time: 31
Time: 47
Time: 47
Time: 31
Time: 47

wieder ganz deutlich das gleiche System,

das beweist natürlich nur, dass bei mir nix passiert ist,
sonst steckt da keine Aussage dahinter ;)

zu Perfmon kann ich nix sagen, egal was das anzeigen würde, wäre mir egal/ hätte keine Aussage für mich,
solange ein eigener Test nicht geht, ist currentTimeMillis() so ungenau wie bekannt
 

Wildcard

Top Contributor
Es ist tatsächlich so, dass System outs Messungen total verändern können. Wenn ich sowas mache, dann alle Ausgaben in Variablen belassen und am Ende ausgeben. So ganz genau konnte ich mir schon damals nicht erklären was da passiert ???:L
 

0xdeadbeef

Top Contributor
Habe mal selber einen kleinen Test geschrieben - nicht für mich, sondern für bereitwillige Tester, bei denen der Systemtimer ohne diesen Workaround mit 10ms läuft. Bei mir macht das Ein- und Auskommentieren erwartungsgemäß keinen Unterschied, weil der Systemtimer so oder so mit 1ms läuft.

Meine Werte sind:
Code:
Min:  0
Max:  16
Mean: 3

Daß die Werte bei so kleinen Sleep-Perioden jittern, ist absolut zu erwarten! Bloß durch den 1ms-Systemtimer wird Windows ja noch nicht zu einem Echtzeitsystem.

Wie gesagt: wichtig ist, vorher mit "perfmon" (einfach in der Kommandozeile eingeben) zu prüfen, ob man ohne "Trick17" deutlich unter 1000 Interrupts hat und mit "Trick17" mehr als 1000. Dazu in das Meßfenster rechts klicken, dann "Leistungsindikatoren hinzufügen", dann Datenobjekt = Prozessor, Leistungsindikator = Interrupts/s-.
Bei mir sind es ca. 1300 Interrupt/s -> ich habe einen 1ms-Timer.

Hier der Test.

Code:
public class TimerTest {

	public static void main(String[] args) throws Exception {
		trick17();
		Thread.sleep(500);
		int minTime = Integer.MAX_VALUE;
		int maxTime = 0;
		int ctrTime = 0;
		int meanTime = 0;
		long sumTime = 0;
		for (int i = 0; i < 4000; i++) {
			long timeStamp = System.currentTimeMillis();
			Thread.sleep(3);
			int curTime = (int)(System.currentTimeMillis() - timeStamp);
			ctrTime++;
			sumTime += curTime;
			meanTime = (int)(sumTime/ctrTime);
			if (curTime > maxTime)
				maxTime = curTime;
			if (curTime < minTime)
				minTime = curTime;

		}
		System.out.println("Min:  " + minTime);
		System.out.println("Max:  " + maxTime);
		System.out.println("Mean: " + meanTime);
	}

	static void trick17() {
		new Thread() {
			{
				this.setDaemon(true);
				this.start();
			}

			public void run() {
				while (true) {
					try {
						Thread.sleep(Integer.MAX_VALUE);
					} catch (InterruptedException ex) {
						ex.printStackTrace();
					}
				}
			}
		};
	}

}
 
S

SlaterB

Gast
?
ich bekomme genau die gleichen Ergebnisse, also vor allem mean = 3,
max in drei Durchläufen 78, 31, 16, solche Aussetzer kann man in nebenläufigen Betriebssystemen ja wohl kaum verhindern,

dass der Durchschnitt 3 sein wird sieht man ja auch schon an meinem Log aus dem zweiten Posting,
aber was bringt das? trotzdem ist die Uhr doch ungenau, wenn sie 4x um 0 ms springt und dann 1x um 16,
denn das lassen deine Werte mit Min = 0 und Max = 16 auch stark vermuten,

probier doch mal bitte meinen Test aus mit Ausgabe der Unterschiede pro Schleifendurchgang, gerne auch mit StringBuilder,
auch Wildcard vielleicht?

wenn sich das gleiche Bild mit dem 16-Sprüngen ergibt, worüber diskutieren wir dann eigentlich hier?,
nicht über die Java-Ms-Zeit sondern über die Systemzeit in allen anderen Programmiersprachen? ;)
 

0xdeadbeef

Top Contributor
Mir geht es ja gar nicht so sehr um die Genauigkeit. Wie gesagt ist es bei einem "normalen" Betriebssystem wie XP kaum zu erwarten, daß Timings auf wenige Millisekunden genau eingehalten werden.
Ich versuche in erster Linie herauszufinden, ob die KATASTROPHALEN Nebenwirkungen von Sleep-Perioden kleiner 10ms durch diesen Workaround ausbleiben. Wie gesagt: ich hatte mal in der Firma einen PC, bei dem die Systemuhr schneller lief, wenn man in einem Java-Programm Sleep-Werte unter 10ms benutzt hat. Leider habe ich den aber nicht mehr, also hätte ich in erster Linie gern einen Tester dafür.

Zweitens würde ich gerne wissen, ob man mit diesem Workaround tatsächlich das Aufrufraster systemweit verstellen kann. Auch das kann ich mit meinem PC nicht testen, weil er bereits ohne den Workaround ein 1ms-Raster verwendet.

Nebenbei: daß der Mittelwert genau stimmt, kann kein Zufall sein, ist aber irgendwie auch irritierend. Bei einer einfachen Implementierung wäre zu erwarten, daß die angeforderte Sleep-Zeit im Mittel immer überschritten wird.
Daß das nicht der Fall ist, kann nur bedeuten, daß sich die Virtual Machine oder Windows zumindest die letzte Sleep-Anforderung merkt, die tatsächlich verstrichene Zeit ausmißt und beim nächsten Aufruf kompensiert. Eigentlich muß aber eine Statistik über mehrere Werte geführt werden, weil ja auch die Kompensation falsch sein könnte.
 
S

SlaterB

Gast
du teilst ja am Ende durch die Anzahl der Versuche, bis zur 4 müsste also durchschnittlich bei jedem Versuch 16% Fehler sein,

aber stimmt schon, irgendwie wird ja doch um die 3 ms gemessen wenn genau 5-6 Runden langfristig in einem 16ms-Sprung passen,
werde das gleich mal zusätzlich mit nanoTime() messen

------

und weils dich so brennend interessiert habe ich dann doch perfmon angeschmissen,
schon beim Start von Eclipse gehts von 100 auf bis zu 400 hoch,
beim TimerTest-Programm dann etwas über 1000, ja

bei
Thread.sleep(1000000);
übrigens auch, soviel zur 10er-Teilbarkeit ;)
 

0xdeadbeef

Top Contributor
Hm, alles recht kurios ;)

Habe meinen Testcode nochmal erweitert, um die Häufungen zu beobachten:

Code:
public class TimerTest {
	final static int MAX = 20;
	
	public static void main(String[] args) throws Exception {		
		trick17();
		Thread.sleep(500);
		int statistics[] = new int[MAX+1];
		int minTime = Integer.MAX_VALUE;
		int maxTime = 0;
		int ctrTime = 0;
		int meanTime = 0;
		long sumTime = 0;
		
		for (int i=0; i<MAX+1; i++)
			statistics[i] = 0;
		
		for (int i = 0; i < 4000; i++) {
			long timeStamp = System.currentTimeMillis();
			Thread.sleep(3);
			int curTime = (int)(System.currentTimeMillis() - timeStamp);
			if (curTime < MAX)
				statistics[curTime]++;
			else
				statistics[MAX]++;
			ctrTime++;
			sumTime += curTime;
			meanTime = (int)(sumTime/ctrTime);
			if (curTime > maxTime)
				maxTime = curTime;
			if (curTime < minTime)
				minTime = curTime;

		}
		System.out.println("Min:  " + minTime);
		System.out.println("Max:  " + maxTime);
		System.out.println("Mean: " + meanTime+"\n");
		for (int i=0; i<MAX+1; i++)
			System.out.println(i+" ms: " + statistics[i]);
		System.out.println(">"+MAX+" ms: " + statistics[MAX]);
	}

	static void trick17() {
		new Thread() {
			{
				this.setDaemon(true);
				this.start();
			}

			public void run() {
				while (true) {
					try {
						Thread.sleep(Integer.MAX_VALUE);
					} catch (InterruptedException ex) {
						ex.printStackTrace();
					}
				}
			}
		};
	}

}

Für 3ms ausgeführt:
Code:
Min:  0
Max:  16
Mean: 3

0 ms: 2999
1 ms: 0
2 ms: 0
3 ms: 0
4 ms: 0
5 ms: 0
6 ms: 0
7 ms: 0
8 ms: 0
9 ms: 0
10 ms: 0
11 ms: 0
12 ms: 0
13 ms: 0
14 ms: 0
15 ms: 375
16 ms: 626
17 ms: 0
18 ms: 0
19 ms: 0
20 ms: 0
>20 ms: 0

Und für 10ms (MAX = 30)
Code:
Min:  0
Max:  16
Mean: 10

0 ms: 1248
1 ms: 0
2 ms: 0
3 ms: 0
4 ms: 0
5 ms: 0
6 ms: 0
7 ms: 0
8 ms: 0
9 ms: 0
10 ms: 0
11 ms: 0
12 ms: 0
13 ms: 0
14 ms: 0
15 ms: 1031
16 ms: 1721
17 ms: 0
18 ms: 0
19 ms: 0
20 ms: 0
21 ms: 0
22 ms: 0
23 ms: 0
24 ms: 0
25 ms: 0
26 ms: 0
27 ms: 0
28 ms: 0
29 ms: 0
30 ms: 0
>30 ms: 0

Wie schon die anderen Tests andeuten, werden überhaupt nur Wartezeiten von 0, 15 und 16 benutzt, um die drei Millisekunden zu approximieren. Bei 10ms ist das Bild praktisch identisch: auch hier werden die 10ms aus den gleichen drei Werten konstruiert.

@SlaterB: es verändert sich zwar der Wert in Perfmon, aber an der Aufrufstatistik ändert sich bei Dir nichts???
Kannst Du es eventuell mal mit/ohne Trick17 ohne Eclipse versuchen? Und hast Du mal darauf geachtet, ob während des Tests mit Trick17 die Systemzeit schneller läuft?
 
S

SlaterB

Gast
mit NanoTime:
Code:
					StringBuilder b = new StringBuilder();
					long time = System.currentTimeMillis();
					long nanoTime = System.nanoTime();
					for (int i = 0; i < 40; i++) {
						nanoTime = System.nanoTime();
						Thread.sleep(7);
						long newNanoTime = System.nanoTime();
						long newTime = System.currentTimeMillis();
						b.append("\nTime: ");
						long timeDif = newTime - time;
						if (timeDif < 10) {
							b.append(" ");
						}
						b.append(timeDif);
						b.append("  ");
						b.append(newNanoTime - nanoTime);
						time = newTime;

					}
					System.out.println(b);

Ausgabe:

Time: 16  7685614
Time:  0  7685334
Time: 16  7792611
Time:  0  7799874
Time: 15  7836750
Time:  0  7770541
Time: 16  7790376
Time:  0  7798756
Time: 15  7799315
Time:  0  7801271
Time: 16  7800153
Time:  0  7797639
Time: 16  7802389
Time:  0  7800712
Time: 15  7806858
Time:  0  7789258
Time: 16  7786185
Time:  0  7797639
Time: 16  7809093
Time:  0  7793728
Time: 15  7797640
Time:  0  7801830
Time: 16  7801830
Time:  0  7804344
Time: 15  7798477
Time:  0  7795963
Time: 16  7851557
Time:  0  7754897
Time: 16  7791493
Time:  0  7806858
Time: 15  7796242
Time:  0  7802109
Time: 16  7789259
Time:  0  7802109
Time: 16  7790934
Time:  0  7801830
Time: 15  7799595
Time:  0  7802388
Time: 16  7817754
Time:  0  7864966

wenn ich trick17() ausschalte, dann habe ich diesmal sogar eine Abweichung,
konstant gibt es zum Anfang des Programms einen Huckel:
Code:
Time: 15  15471799
Time: 16  229079
Time:  0  7762439
Time: 15  7785906
Time:  0  7787861
dürfte hauptsächlich am Programmstart liegen, aber auch bei einer Schleife um diese 40er-Messung gibts ohne trick17() ab und zu Probleme bei der ersten Messung,

mit und ohne trick17() kommts im weiteren Verlauf durchaus auch mal zu Wert bis zu 15ms, so genau wie in der Ausgabe ist das also nicht immer,
als nächstes muss ich dann wohl ne Statistik bauen,

interessant übrigens, dass 7 ms nun gar nicht 7000000 Nanosekunden sind,
gibts da einen Umrechnungsfaktor oder konstanten Aufschlag?

--------

> @SlaterB: es verändert sich zwar der Wert in Perfmon, aber an der Aufrufstatistik ändert sich bei Dir nichts???
> Kannst Du es eventuell mal mit/ohne Trick17 ohne Eclipse versuchen?

bei ms erwarte ich nicht mehr viel, zu NanoSekunden werde ich nun aber auch wie du eine Wertetabelle führen,
gerne dann auch mal ohne Eclipse

die 400 bei perfmon meinte ich nur zum Start von Eclipse, danach wieder 100 und 1000 beim Programm
 

0xdeadbeef

Top Contributor
Öh, Moment?
Willst Du mir sagen, daß currentTimeMillis das Problem ist? Da bin jetzt aber schon etwas baff.
Muß ich gerade mal selber testen. Leider gibt es nanoTime ja erst ab 1.5, oder? Wollte eigentlich 1.4-kompatibel bleiben...

So, hier das Update:

Code:
public class TimerTest {
	final static int MAX = 20;
	
	public static void main(String[] args) throws Exception {		
		trick17();
		Thread.sleep(500);
		
		int statistics[] = new int[MAX+1];
		int minTime = Integer.MAX_VALUE;
		int maxTime = 0;
		int ctrTime = 0;
		int meanTime = 0;
		long sumTime = 0;

		int statisticsMicro[] = new int[MAX+1];
		int minTimeMicro = Integer.MAX_VALUE;
		int maxTimeMicro = 0;
		int ctrTimeMicro = 0;
		int meanTimeMicro = 0;
		long sumTimeMicro = 0;		
		
		for (int i=0; i<MAX+1; i++) {
			statistics[i] = 0;
			statisticsMicro[i] = 0;
		}
		
		for (int i = 0; i < 4000; i++) {
			long timeStamp = System.currentTimeMillis();
			long timeStampNano = System.nanoTime();
			Thread.sleep(3);
			int curTimeMicro = (int)(System.nanoTime() - timeStampNano)/1000;
			int curTime = (int)(System.currentTimeMillis() - timeStamp);
			//ms
			if (curTime < MAX)
				statistics[curTime]++;
			else
				statistics[MAX]++;
			ctrTime++;
			sumTime += curTime;
			meanTime = (int)(sumTime/ctrTime);
			if (curTime > maxTime)
				maxTime = curTime;
			if (curTime < minTime)
				minTime = curTime;
			//us
			if (curTimeMicro < MAX*1000)
				statisticsMicro[curTimeMicro/1000]++;
			else
				statisticsMicro[MAX]++;
			ctrTimeMicro++;
			sumTimeMicro += curTimeMicro;
			meanTimeMicro = (int)(sumTimeMicro/ctrTimeMicro);
			if (curTimeMicro > maxTimeMicro)
				maxTimeMicro = curTimeMicro;
			if (curTimeMicro < minTimeMicro)
				minTimeMicro = curTimeMicro;

		}
		System.out.println("Min:  " + minTime  + "ms (" + minTimeMicro+" us)");
		System.out.println("Max:  " + maxTime  + "ms (" + maxTimeMicro+" us)");
		System.out.println("Mean: " + meanTime + "ms (" + meanTimeMicro+" us)"+"\n");
		for (int i=0; i<MAX+1; i++)
			System.out.println(i+" ms: " + statistics[i] + " ("+statisticsMicro[i]+")");
		System.out.println(">"+MAX+" ms: " + statistics[MAX] + " ("+statisticsMicro[MAX]+")");
	}

	static void trick17() {
		new Thread() {
			{
				this.setDaemon(true);
				this.start();
			}

			public void run() {
				while (true) {
					try {
						Thread.sleep(Integer.MAX_VALUE);
					} catch (InterruptedException ex) {
						ex.printStackTrace();
					}
				}
			}
		};
	}

}

Und das Ergebnis:

Code:
Min:  0ms (2996 us)
Max:  16ms (7285 us)
Mean: 3ms (3906 us)

0 ms: 2999 (0)
1 ms: 0 (0)
2 ms: 0 (1)
3 ms: 0 (3859)
4 ms: 0 (128)
5 ms: 0 (8)
6 ms: 0 (3)
7 ms: 0 (1)
8 ms: 0 (0)
9 ms: 0 (0)
10 ms: 0 (0)
11 ms: 0 (0)
12 ms: 0 (0)
13 ms: 0 (0)
14 ms: 0 (0)
15 ms: 375 (0)
16 ms: 626 (0)
17 ms: 0 (0)
18 ms: 0 (0)
19 ms: 0 (0)
20 ms: 0 (0)
>20 ms: 0 (0)

Wie man sieht, liefert tatsächlich currentTimeMillis() Bullshit zurück, denn in Wirklichkeit werden die 3ms viel exakter eingehalten. Der Maximalwert ist in Wirklichkeit um die 7ms, die komischen Häufungen bei 0, 15 und 16ms existieren überhaupt nicht. Unter diesen Rahmenbedingungen kann man Messungen mit currentTimeMillis() ja wirklich vollständig vergessen.
 
S

SlaterB

Gast
tja, es ist wie es ist

hier nochmal arg zusammengeschustert ein Verteilungstest
Code:
public class TimerTest {
	final static int MAX = 20;

	public static void main(String[] args) throws Exception {
		trick17();
		Thread.sleep(500);
		int statistics[] = new int[MAX + 1];
		int minTime = Integer.MAX_VALUE;
		int maxTime = 0;
		int ctrTime = 0;
		int meanTime = 0;
		long sumTime = 0;

		long dif = 0;
		int mean = 3892000;
		for (int i = 0; i < MAX + 1; i++)
			statistics[i] = 0;

		for (int i = 0; i < 1000; i++) {
			long timeStamp = System.nanoTime();
			Thread.sleep(3);
			int curTime = (int) (System.nanoTime() - timeStamp);
			curTime -= mean;
			dif += Math.abs(curTime);
			curTime /= 1000;
			// if (i < 20) {
			// System.out.println(curTime);
			// }

			if (curTime < 0) {
				statistics[0]++;
			} else if (curTime < MAX) {
				statistics[curTime]++;
			} else {
				statistics[MAX]++;
			}
			ctrTime++;
			sumTime += curTime;
			meanTime = (int) (sumTime / ctrTime);
			if (curTime > maxTime)
				maxTime = curTime;
			if (curTime < minTime)
				minTime = curTime;

		}
		System.out.println("Min:  " + minTime);
		System.out.println("Max:  " + maxTime);
		System.out.println("Mean: " + meanTime);
		System.out.println("Dif: " + dif + "\n");
		for (int i = 0; i <= MAX; i++) {
			System.out.println((i + 100) + " ms: " + statistics[i]);
		}
	}

	static void trick17() {
		new Thread() {
			{
				this.setDaemon(true);
				this.start();
			}

			public void run() {
				while (true) {
					try {
						Thread.sleep(Integer.MAX_VALUE);
					} catch (InterruptedException ex) {
						ex.printStackTrace();
					}
				}
			}
		};
	}
}
hab leider grad keine Lust, alles richtig zu benennen und zu kommentieren ;)

grob gesagt ergibt sich eine nanoTime() von rund 3.900.000 pro Durchlauf,
davon ziehe ich nun einen vorher gemachten Erfahungswert ab so dass nur die interessanten hinteren variablen Zahlen bleiben,
noch geteilt usw, damits ins Array passt und gibt bei mir ne Verteilung von

Code:
Min:  -603
Max:  2360
Mean: 12
Dif: 23997897

100 ms: 93
101 ms: 8
102 ms: 12
103 ms: 4
104 ms: 21
105 ms: 22
106 ms: 17
107 ms: 40
108 ms: 34
109 ms: 79
110 ms: 107
111 ms: 178
112 ms: 136
113 ms: 61
114 ms: 40
115 ms: 17
116 ms: 15
117 ms: 13
118 ms: 8
119 ms: 6
120 ms: 89
die Werte sind relativ aussagelos, wichtig ist nur der Vergleich zu ohne trick17(),
und da gibts bei mir keinen nennenswerten Unterschied, bis auf den Huckel am Anfang, der regelmäßig zu einem hohen Anfangswert und damit
Max: > 10000
führt, das erhöht auch den Mean und Dif,
im Grunde bleibt die Verteilung aber gleich,
egal ob in Eclipse oder ohne,

Fazit für mich: NanoTime bei beiden sehr genau,
MilliTime bei beiden und anscheinend auch auf deinem PC ungenau wie man es kennt,

ob die 1000 statt 100 in perfmon irgendwo sonst irgendeine Auswirkung haben kann ich nicht sagen
 
S

SlaterB

Gast
> Und hast Du mal darauf geachtet, ob während des Tests mit Trick17 die Systemzeit schneller läuft?

ach je, die Frage habe ich bewußt die ganze Zeit ausgeklammert,
das ist ja nicht zu messen, dazu will ich kein (aktuelles TestProgramm-)Statement abgeben

über Monate und Jahre gesehen ist meine PC-Uhr locker 1 Min. pro Monat zu schnell, möchte ich vermuten,
aber belegen oder beursachen kann ich das nicht, verwende auch nicht so viel Thread.sleep() ;)
 

0xdeadbeef

Top Contributor
Wir reden hier nicht von solchen Kleinigkeiten. Bei meinem ehemaligen Test-PC war eine Minute in ein paar Sekunden rum. Da konnte man die analoge Windows-Uhr im Kreis flitzen sehen. Nach einem kurzen (!) Test war die Systemzeit um mehrere Minuten daneben.
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
N Minecraft Frage für einen Minecraft Server Spiele- und Multimedia-Programmierung 2
Drachenbauer Speicher-Tool für ein Spiel schreiben Spiele- und Multimedia-Programmierung 13
B Deepmind Poker Bot für PokerStars konfigurieren? Spiele- und Multimedia-Programmierung 2
G Minecraft PlayerBot (Listener Thread für jeden Spieler?) Spiele- und Multimedia-Programmierung 3
K Wie bekomme ich eine Transition für alle Objekte zum stoppen? Spiele- und Multimedia-Programmierung 1
E Organisation für Game Spiele- und Multimedia-Programmierung 1
Excess Ballerfisch für Android Spiele- und Multimedia-Programmierung 3
coolian ich brauche irgendeine gui lib für lwjgl2 Spiele- und Multimedia-Programmierung 51
krgewb Anderer Algorithmus für Bounding Box Spiele- und Multimedia-Programmierung 9
MiMa MP3 Dateien für Metadaten abgleichen Spiele- und Multimedia-Programmierung 0
Freshy Bot für Discord Spiele- und Multimedia-Programmierung 61
R Ideen für die Backend-Entwicklung eines Games gesucht Spiele- und Multimedia-Programmierung 8
G Mikrophon-/Audiosteuerung für einen Character Spiele- und Multimedia-Programmierung 1
P Tennis- Spielstand- Zähler für Schule programmieren Spiele- und Multimedia-Programmierung 6
M Logik für ein Quiz Spiele- und Multimedia-Programmierung 7
P Hilfe für Seminar Arbeit Spiele- und Multimedia-Programmierung 9
MiMa Metadaten für Multimedia Daten ermitteln Spiele- und Multimedia-Programmierung 4
G Übungsprogramm für Matheaufgaben Spiele- und Multimedia-Programmierung 1
F Algorithmus für bessere Kollisionsabfragen Spiele- und Multimedia-Programmierung 10
S Bilder Für Schachfiguren Spiele- und Multimedia-Programmierung 14
Timo_neu_in_java Suche etwas einfaches für Anfänger Spiele- und Multimedia-Programmierung 6
I Minecraft Suche Plugin Developer für Minecraft Netzwerk! Spiele- und Multimedia-Programmierung 2
S GUI erstellen für Text Adventure Spiele- und Multimedia-Programmierung 4
S Eigene Klasse vec_t - 3 oder 4 Einheiten für x, y, z und w Spiele- und Multimedia-Programmierung 11
R Vererbbarer GameLoop für Engine Spiele- und Multimedia-Programmierung 14
J Vektor für Gravitation erzeugen Spiele- und Multimedia-Programmierung 34
I Minecraft: Craftingrecipe für Braustand ändern Spiele- und Multimedia-Programmierung 9
Z Minimax-Algorithmus für TicTacToe Spiele- und Multimedia-Programmierung 5
H KI für Spiele Spiele- und Multimedia-Programmierung 1
S Pssende Datenstruktur für ein Netz Spiele- und Multimedia-Programmierung 5
S MouseEvents für Sprites Spiele- und Multimedia-Programmierung 3
I Spectator Modus für Spiel ähnlich zu Terraria Spiele- und Multimedia-Programmierung 8
K Bestes Bildformat für Spielegrafiken und deren Einbindung in Java Spiele- und Multimedia-Programmierung 2
J mehrere Listener für einen Button / Label Spiele- und Multimedia-Programmierung 1
C Port umleiten: lesen und schreiben für MCServer-Client über Skype Spiele- und Multimedia-Programmierung 0
J Musik Bibliothek für GUI Spiele- und Multimedia-Programmierung 7
B Hauptmenü für Spiel Spiele- und Multimedia-Programmierung 1
R Ratschlag für 2D-3D Engine für die Spieleentwicklung gesucht Spiele- und Multimedia-Programmierung 4
Androbin KI für Verfolgung im Raster Spiele- und Multimedia-Programmierung 2
A Bot für Browsergame Spiele- und Multimedia-Programmierung 2
H Tutorials für Fortgeschrittene 3D-Anwedungen Spiele- und Multimedia-Programmierung 2
lord239123 suche Graphiker für ein Pokemon-Spiel Spiele- und Multimedia-Programmierung 6
Furtano Vektoren für Bewegung für eine 2D-Simulation Spiele- und Multimedia-Programmierung 3
T Sinusgenerator für eine Hp Spiele- und Multimedia-Programmierung 8
J Menü für Snakespiel in einzelnem JFrame Spiele- und Multimedia-Programmierung 5
M Minecraft weitere Java Entwickler für minecraft projekt gesucht Spiele- und Multimedia-Programmierung 0
Guybrush Threepwood Ketzerische Frage: Opus-Codec für Java Spiele- und Multimedia-Programmierung 14
L Hilfe bei Klassendesign für Spiel Spiele- und Multimedia-Programmierung 2
N Animationen für ein 2D game Spiele- und Multimedia-Programmierung 6
S Aufbau für 2D Spiele Spiele- und Multimedia-Programmierung 7
L Client für ein Browsergame Spiele- und Multimedia-Programmierung 21
Devil0s Swing Elemente für Inventar? Spiele- und Multimedia-Programmierung 9
Kenan89 Ansatzfrage: Kartenspiel für 2 Spieler Online Spiele- und Multimedia-Programmierung 3
F Ideen für spiel Spiele- und Multimedia-Programmierung 4
P Spielfeld für RPG Spiele- und Multimedia-Programmierung 15
Hoppelmann Alphamap (Bild) für 3D-Terrain generieren Spiele- und Multimedia-Programmierung 2
S Algorithmus zur Ressourcesuche für die KI Spiele- und Multimedia-Programmierung 5
M Farbwerte für Flächen aus einem Bild erkennen Spiele- und Multimedia-Programmierung 3
K Einfache Engine für einfaches 3D gesucht Spiele- und Multimedia-Programmierung 10
C KI für Skatspiel - Wie können die Computerspieler eigenständig handeln? Spiele- und Multimedia-Programmierung 10
S Aufbau von Klassen für Spiel Spiele- und Multimedia-Programmierung 13
Kenan89 Kleines Projekt für Java Spiele- und Multimedia-Programmierung 5
M Empfehlungen für ein 2D-Jump'n'run Spiele- und Multimedia-Programmierung 4
A Grundlagensuche für Spiel Spiele- und Multimedia-Programmierung 8
C Wo ist der MP3 Plugin für JMF? Spiele- und Multimedia-Programmierung 3
qwerqer Design Pattern gesucht für Spielregeln Spiele- und Multimedia-Programmierung 2
M Java als Programmiersprache für kommerzielle Spieleentwicklung? Spiele- und Multimedia-Programmierung 3
K Game Engine für selbstprogrammiertes Spiel Spiele- und Multimedia-Programmierung 27
Y Warum Thread für Spieleprogrammierung? Spiele- und Multimedia-Programmierung 27
A Music für Android game Spiele- und Multimedia-Programmierung 3
Gossi Probleme beim Laden der Images aus dem "Tutorial für Java-Spiele" Spiele- und Multimedia-Programmierung 4
M Minecraft Suche Java Programmierer (für Minecraft) Spiele- und Multimedia-Programmierung 2
Luk10 Tipps für bessere Animationen / Grafik Engine Spiele- und Multimedia-Programmierung 2
T 2D Menü für 3D Spiel Spiele- und Multimedia-Programmierung 5
T Grundlagenwissen für den 3D Raum Spiele- und Multimedia-Programmierung 6
I getSubImage sorgt für starken Performanceeinbruch Spiele- und Multimedia-Programmierung 6
M technologie für video, webcam & co Spiele- und Multimedia-Programmierung 25
C Java für große Spiele geeignet ? Spiele- und Multimedia-Programmierung 101
D Libraryempfehlung für Effekte Spiele- und Multimedia-Programmierung 3
B Spiele programmieren für ein Fenster? Spiele- und Multimedia-Programmierung 14
D Tabelle für Spiel Spiele- und Multimedia-Programmierung 3
N Grundlagen für ein Jump&Run Spiele- und Multimedia-Programmierung 3
S Datenbank gesucht für Bilder(gif-dateien) Spiele- und Multimedia-Programmierung 5
J Suche 3D Programm für jMonkeyEngine Spiele- und Multimedia-Programmierung 5
W 3D-APIs für Java - Eine Übersicht Spiele- und Multimedia-Programmierung 8
D Problem beim Öffnen einer PHP für eine Highscore Spiele- und Multimedia-Programmierung 5
S Game Client für kleine Competition Spiele- und Multimedia-Programmierung 3
F Programm für Bildbearbeitung gesucht: Skalieren und Speichern Spiele- und Multimedia-Programmierung 6
K Lösungsansätze für ein Spiel Spiele- und Multimedia-Programmierung 2
Plastagen Frameworls für Animationen und co Spiele- und Multimedia-Programmierung 3
aze Wie Transform3D für PosPathInterpolator bestimmen Spiele- und Multimedia-Programmierung 8
M Musik für Spiel wo downloaden? Spiele- und Multimedia-Programmierung 7
R Netzwerkstruktur für ein kleines Spiel Spiele- und Multimedia-Programmierung 8
O KI (künstliche Intelligenz) für Schachlogik Spiele- und Multimedia-Programmierung 4
J Brauche denkanstoß für kleines grafikframework Spiele- und Multimedia-Programmierung 3
A Countdown-Timer für Spiel Spiele- und Multimedia-Programmierung 4
J Tips für ein kleines Pong-Applet Spiele- und Multimedia-Programmierung 4
S Ein Thread für alle Animationen oder mehrere? Spiele- und Multimedia-Programmierung 2
S Grafik erstellen für Java Spiel Spiele- und Multimedia-Programmierung 8
G Javasimulatoren für Siemenshndys Spiele- und Multimedia-Programmierung 11

Ähnliche Java Themen

Neue Themen


Oben