Ich habe da ein merkwürdiges Problem.
Für ein Spiel möchte ich alle X Millisekunden einen Bildschirm berechnen. Das mache ich, indem ich einen folgenden Thread laufen lasse:
Alle "GameController.timePerFrame" Millisekunden soll ein Repaint erzwungen werden (geschieht in der Funktion redraw().
Allerdings möchte ich zwischenzeitlich ein bißchen Rechenzeit freigeben. Ganz ohne "Thread.sleep()" verbraucht das Spiel einen deutlichen Anteil der CPU-Ressourcen, mit Sleep sinkt das in den kaum noch meßbaren Bereich. Deshalb rechnen ich dann, wenn kein Redraw erfolgen muß, die Zeit bis zum nächsten Redraw aus und lege mich dann solange schlafen.
Kurioserweise führt diese Variante (im Beispiel auskommentiert) dazu, daß die in einem zweiten Thread abgespielte Musik (MOD-Player) stottert.
Wohlbemerkt: wenn mein Hauptthread sich "zu lange" schlafen legt, stottert die Musik aus dem zweiten Thread. Beschneide ich die Zeit, die ich den Haupt-Thread maximal schlafen lege auf einen kleineren Wert, dann scheint alles wunderbar zu funktionieren. Der zweite Thread blockiert übrigens immer dann, wenn in die "Line" keine Sounddaten mehr geschrieben werden können. Er verbraucht daher auch ohne Sleep kaum Rechenzeit und sein Aufrufraster ist durch die internen Puffer der Line und den zusätzlichen 2k-Puffer des Modplayers eigentlich unkritisch.
Mir ist nur absolut nicht klar, was eigentlich das Problem ist. Ich habe ewig mit Prioritäten und Sleep/Yield in beiden Threads rumprobiert, aber ich komme immer wieder darauf zurück, daß das Problem genau dann auftaucht, wenn ich meinen Haupt-Thread zu lange schlafen lege. Wobei mir nicht ersichtlich ist, was für den zweiten Thread oder die JVM der Unterschied ist, ob ich meinen Thread einmal für 30ms oder 6mnal für 5ms schlafen lege...
Hat jemand ähnliche Erfahrungen oder kann mir sagen, was da eigentlich genau das Problem ist? Ich kann jetzt natürlich den "Grenzwert" für die maximale Sleep-Periode irgendwie festlegen, habe aber die Befürchtung, daß das Problem auf anderen Rechnern trotzdem wieder auftritt...
Für ein Spiel möchte ich alle X Millisekunden einen Bildschirm berechnen. Das mache ich, indem ich einen folgenden Thread laufen lasse:
Code:
public void run() {
long timeBaseRepaint = System.currentTimeMillis();
while (true) {
long t = System.currentTimeMillis();
if (t >= timeBaseRepaint + GameController.timePerFrame) {
timeBaseRepaint += GameController.timePerFrame;
redraw(); // does also repaint
} else {
try {
// time until next frame
long diff = timeBaseRepaint + GameController.timePerFrame - t;
// doesn't work well
/*
if (diff>1)
Thread.sleep(diff);
else
Thread.sleep(1);
*/
if (diff>5)
Thread.sleep(5);
else
Thread.sleep(1);
} catch (InterruptedException ex) {}
}
}
}
Alle "GameController.timePerFrame" Millisekunden soll ein Repaint erzwungen werden (geschieht in der Funktion redraw().
Allerdings möchte ich zwischenzeitlich ein bißchen Rechenzeit freigeben. Ganz ohne "Thread.sleep()" verbraucht das Spiel einen deutlichen Anteil der CPU-Ressourcen, mit Sleep sinkt das in den kaum noch meßbaren Bereich. Deshalb rechnen ich dann, wenn kein Redraw erfolgen muß, die Zeit bis zum nächsten Redraw aus und lege mich dann solange schlafen.
Kurioserweise führt diese Variante (im Beispiel auskommentiert) dazu, daß die in einem zweiten Thread abgespielte Musik (MOD-Player) stottert.
Wohlbemerkt: wenn mein Hauptthread sich "zu lange" schlafen legt, stottert die Musik aus dem zweiten Thread. Beschneide ich die Zeit, die ich den Haupt-Thread maximal schlafen lege auf einen kleineren Wert, dann scheint alles wunderbar zu funktionieren. Der zweite Thread blockiert übrigens immer dann, wenn in die "Line" keine Sounddaten mehr geschrieben werden können. Er verbraucht daher auch ohne Sleep kaum Rechenzeit und sein Aufrufraster ist durch die internen Puffer der Line und den zusätzlichen 2k-Puffer des Modplayers eigentlich unkritisch.
Mir ist nur absolut nicht klar, was eigentlich das Problem ist. Ich habe ewig mit Prioritäten und Sleep/Yield in beiden Threads rumprobiert, aber ich komme immer wieder darauf zurück, daß das Problem genau dann auftaucht, wenn ich meinen Haupt-Thread zu lange schlafen lege. Wobei mir nicht ersichtlich ist, was für den zweiten Thread oder die JVM der Unterschied ist, ob ich meinen Thread einmal für 30ms oder 6mnal für 5ms schlafen lege...
Hat jemand ähnliche Erfahrungen oder kann mir sagen, was da eigentlich genau das Problem ist? Ich kann jetzt natürlich den "Grenzwert" für die maximale Sleep-Periode irgendwie festlegen, habe aber die Befürchtung, daß das Problem auf anderen Rechnern trotzdem wieder auftritt...