Wie kann ich eine Java While-Schleife davon abhalten, & gt; 50% meiner CPU zu essen?
Okay, getestet habe ich diese auf ein leeres Programm, und nur mit einer while(true){} läuft mir Gaben, >50% an meiner CPU. Ich habe ein Spiel, an dem ich arbeite, benutzt eine while-Schleife, wie es die main-loop, und es ist CPU ist bei 100 die ganze Zeit.
Wie bekomme ich Java, etwas zu wiederholen, über und über, ohne zu Essen bis >50% meiner CPU nur zu tun, das zu wiederholen?
InformationsquelleAutor der Frage William | 2009-02-24
Du musst angemeldet sein, um einen Kommentar abzugeben.
Hinzufügen schlafen, um den thread in Leerlauf für einige Intervall:
- Thread.Schlaf
Ohne Schlaf, die while-Schleife verbrauchen alle computing-Ressourcen, die verfügbar ist. (Zum Beispiel, rein theoretisch, zu 100% in eine single-core-system, oder 50% in einem dual-core, und so weiter.)
Beispielsweise wird der folgende Zyklus einmal über eine
while
Schleife etwa alle 50 Millisekunden:Sollte dies bringen die CPU-Auslastung ziemlich.
Mit einem sleep in der Schleife, das Betriebssystem wird auch genug geben, die system Zeit für andere threads und Prozessen zu tun, Ihre Sachen, so dass das system reagieren als gut. Zurück in die Tage von single-core-Systeme und operative Systeme mit nicht-so-gute Planer, Schleifen, wie dies gemacht haben könnte, das system nicht mehr reagiert.
Da das Thema Einsatz von
while
Schleifen für ein Spiel kam, wenn das Spiel geht mit einer GUI, die Spiel-Schleife muss in einen eigenen thread, da sonst die GUI selbst wird nicht mehr reagiert.Wenn das Programm ist ein Konsole-basiertes Spiel, dann einfädeln ist nicht ein Problem, aber mit graphical user interfaces, die event-driven -, lange-Leben-Schleife in den code wird die GUI nicht mehr reagiert.
Threading und so sind ziemlich knifflig Gebiete der Programmierung, insbesondere beim Einstieg, daher schlage ich vor, eine weitere Frage erhoben werden, wenn es notwendig wird.
Der folgenden ist ein Beispiel für eine Swing-Anwendung in einer
JFrame
welche updates einJLabel
enthält der zurückgegebene Wert vonSystem.currentTimeMillis
. Der Update-Prozess erfolgt in einem separaten thread, und eine "Stop" Taste stoppen Sie den update-thread.Wenige Konzepte das Beispiel soll das verdeutlichen:
while
Schleife mit einer Schleife Bedingung, die nichttrue
aber durch eineboolean
die bestimmen, ob Sie die Schleife am Leben.Thread.sleep
Faktoren in einer tatsächlichen Anwendung.Bitte ich um Entschuldigung für das lange Beispiel:
Einige Ressourcen über threading und mit Swing:
InformationsquelleAutor der Antwort coobird
Thread.Schlaf kann nicht die ganze Antwort. Für die meisten Spiele, es gibt zu viel CPU für die Menge der Arbeit benötigt werden. Einfach schlafen für eine gewisse Zeit ist nicht effizient, da Sie wahrscheinlich entweder noch brennen zu viele Ressourcen, oder nicht genug. Möchten Sie in der Regel Zeit, Ihre Arbeit in irgendeiner Weise.
Wenn Sie darüber nachdenken, wird der Bildschirm nur updates mit einer bestimmten rate, in der Regel weniger als 100-mal pro Sekunde. Ich bin nicht vertraut mit der Java-api ist für diese Art der Sache, aber was Sie wollen, ist, um herauszufinden, die refresh rate des Monitors und dann update nur ein einziges mal zwischen jeder Aktualisierung.
Weitere, Sie brauchen nicht eine Schleife wie die, die für Ihre Haupt-Schleife, die Sie verwenden können, Timer, rufen Sie Ihren update-code zu regelmäßigen Intervallen. Das ist noch effizienter.
InformationsquelleAutor der Antwort Erik Funkenbusch
Du ja busy-waiting, das heißt, Sie Schleifen Ihre CPU ständig auf der Prüfung eine oder mehrere Bedingungen aus, bis Sie true ist.
Thread.sleep()
ist nicht die Lösung. Mitwait()
undnotify()
Methoden können Sie genau das tun, was Sie versuchen, aber viel effizienter. Grundsätzlich ermöglicht dieser Mechanismus ein thread auf ein Objekt, bis das Objekt entscheidet, etwas passiert ist und will aufwecken aller threads auf ihm schlafen.Code exmaples finden hier und hier.
Diese sollten Sie Ihre Lösung, und nicht verstecken Sie Ihre busy-wait mit einem timer.
InformationsquelleAutor der Antwort Yuval Adam
In der Regel in einem Spiel-Schleife werden Sie eine pause für ein bisschen... zum Beispiel: http://developers.sun.com/mobility/midp/articles/game/
InformationsquelleAutor der Antwort TofuBeer
Während ja, könnten Sie tun, ein
wie die akzeptierte Antwort vorschlagen, die Sie auch nennen könnte,
Dies wird Ihnen sagen, dass der Prozessor ein context-switch. Anderen threads warten, um ausgeführt zu werden (wie der GUI-zeichnen-thread) wird dann ausgeführt, und die Maschine wird aufhören, das Gefühl langsam.
Sleep(0) auch bei der Maximierung der Zeit, gegeben durch das Betriebssystem auf Sie Anwendung, da der thread wird sofort zurück in der Prozessor-Warteschlange (statt 50ms warten, bevor Sie dies tun) also, wenn kein anderer thread, wo warten, Sie thread weiter ausgeführt wird.
InformationsquelleAutor der Antwort Frederic Morin
Wie es scheint, dein thread ist busywaiting. Das heißt, es ist gefangen in einer Schleife, in der es nichts tut. In einer solchen situation, wird es kauen, bis eine Menge von cpu-Zyklen keine Wirkung.
Wie bereits erwähnt, von anderen, Thread.der Schlaf ist die Antwort.
InformationsquelleAutor der Antwort Rob Lachlan
Das ist swing-Verwandteaber die Idee bleibt die gleiche: versuchen Sie, Observer-Musters statt
wile(true)
.InformationsquelleAutor der Antwort yanchenko
Wie wäre es mit einer Quarz-Spring-basierte scheduler, der hält die Arbeit macht immer und immer wieder, in wiederholten Intervallen.
InformationsquelleAutor der Antwort Franklin
Wenn es ein interrupt ist es wohl für einen Grund. Einen besseren Weg, dies zu behandeln ist
Aber diese Schleife die nichts tut, so schlage ich vor, Sie einfach zu löschen. Es ist ziemlich selten, dass Sie möchten, zu beschäftigt, warten Sie, bis eine Bedingung (In diesem Fall ist der Zustand Klasse ist die bessere Wahl) in der Regel können Sie verwandeln das gleiche Verhalten zu müssen, um eine Schleife an alle.
InformationsquelleAutor der Antwort Peter Lawrey