# Frage zu Threads



## JavaException (14. Sep 2010)

Hallo,
eigetnlich verstehe ich das Prinzip von Thread schon einigermaßen, allerdings ist mir bei Spieletutorials öfter eine bestimmte Vorgehensweise aufgefallen die ich noch nicht ganz nachvollziehen kann. 
Ich erkär kurz mal den Grundaufbau, also:
Man erstellt eine Klasse und leitet diese von Canvas/JPanel ab. Im Konstruktor werden dann verschiedene Einstellungen wie zb. Größe,Position,ein Frame für aussenrum... erstellt. Zum schluss wird dann immer ein neuer Thread erzeugt und auch gleich gestartet.
Sieht dann so ungefähr aus:

```
public class GameCanvas extends Canvas implements Runnable {
public GameCanvas() {
Frame f = new Frame();
f.setSize(..);
f.add(this);
.........
new Thread(this).start();
}
}
```

In der run()-Mehtode läuft jetzt der sog. GameLoop. Was sich mir jetzt nicht ganz erschließt: Welche aufgabe übernimmt nun welcher Thread? Es gibt ja den ursprünglichen Thread und den neu erstellten.
So wie ich das verstanden habe, läuft jetzt die run-Methode "parallel" zum ursprünglichen Thread. Die Befehle in der run-Methode werden aber immer noch sequentiell abgearbeitet (ausser vielleicht bei dem repaint() Aufruf). Das ganze Spiele läuft doch aber im GameLoop ab, wo bleibt dann der andere Thread? Ich würds ja noch verstehen wenn nach dem aufruft 
	
	
	
	





```
new Thread(this).start();
```
weitere Methodenaufrufe kommen würden. Dann würde nämlich die run Methode schonmal laufen und die Befehle danach trotzdem "gleichzeitig" ausgeführt werden.
Gleich noch ne Frage zur Berechnung der FPS: Die Zeichenoperationen laufen alle in paint ab. Paint wird ja durch repaint() im GameLoop aufgerufen. Allerdings passiert das ja nicht sofort. Es wird sozusagen nur der Aufruf von paint angefordert. Hab mir mal per System.out.print testweise was ausgeben lassen, und da sieht man auch das der GameLoop schon mehrmals durchlaufen wurde bis es überhaupt zum Aufruf von paint kommt. Allerdings setzten doch die Berechnungen der fps gerade voraus, dass die Zeichenoperationen ausgeführ werden. Hier mal der Code:

```
while(!exit) {
            try {
                
            long startTime = System.currentTimeMillis();
                
            repaint();

            Thread.yield();

            long executionTime = System.currentTimeMillis() - startTime;
            if (executionTime < MAX_GAME_SPEED) {
                Thread.sleep(MAX_GAME_SPEED - executionTime);
            }
        } catch (Exception e) {}
        }
```

Ist das so überhaupt sinnvoll?


----------



## SlaterB (14. Sep 2010)

was ist denn 'der ursprüngliche Thread'? den kennt nicht jeder so auf Anhieb,

klar ist dass irgendwer den Konstruktor von Canvas aufruft, irgendein Thread muss schon da sein,
anfangs z.B. der main-Thread der die main-Methode ausführt oder auch ein GameLoop-Thread wie du im weiteren andeutest,

diese könnten auch die Aufgaben vom GameCanvas-Thread übernehmen, stimmt,
wenn der ursprüngliche Thread nichts mehr zu tun hat, könnte der direkt run() von GameCanvas aufrufen,
es würde kein zweiter Thread benötigt, das ginge problemlos

falls es sich um den GameLoop-Thread handeln, so erstellt der vielleicht anfangs die GUI
und kommt dann zu der MAX_GAME_SPEED-Schleife, für diesen beschäftigten Thread wäre es ungünstig,
die GameCanvas-Aufgaben auch zu übernehmen

edit:
ach, GameLoop ist bei dir der zweite Thread? dann ist wieder eher unklar wer der erste ist, für main habe ich die Möglichkeiten angedeutet,
aber wie wäre es etwa, wenn GameCanvas über einen Button erzeugt wird, vom AWT-Thread aus, der die GUI blockiert,
der dürfte damit nicht belastet werden,

oder es soll möglich sein, zwei Spiele parallel laufen zu lassen,  
hat schon seine Vorteile wenn Dinge autark laufen, egal wer sie aufruft und egal welche Threads sonstwo laufen,
ist nicht schlimm wenn ein Thread beendet und dafür ein andere gestartet wird, auch wenn man es in bestimmten Konstellationen vermeiden könnte



------

die Schleife sieht brauchbar aus, das paint() wird entweder aufgrund des yields() 
vor Zeile 10 ausgeführt, dann musst nur wenig geschlafen werden,

ansonsten ist das sleep() über eine längere Zeit und währenddessen ist dann Zeit fürs paint()

grundsätzlich mag das also funktionieren, muss auch nicht exakt sein,
wenn mal ein FPS ausfällt, ist das kein Beinbruch

für richtig hochwertige Anzeigen würde man sich eher nicht auf indirektes unkontrollieres repaint()/paint() einlassen,
im einfachen Falle kommt das aber ausreichend hin


----------



## Quaxli (14. Sep 2010)

Der erste Thread ist der Event Dispatching Thread. Irgendwer muß ja weiterhin permanent Eingaben von Tastatur und Maus entgegen nehmen.


----------



## JavaException (15. Sep 2010)

Hi,
schonmal danke für eure Antworten. 
Also mit ursprünglichen Thread hatte ich den main Thread gemeint. In meiner Canvas Klasse gibts dann eine main Methode die das Objekt erzeugt, also so:


```
public static void main(String[] args) {
        new GameCanvas();
    }
```

Ich erzeuge insgesamt nur den einen Thread im Konstruktor.
Also theoretisch hat der main Thread nach dem Konstruktor nichts mehr zu tun, oder muss der Konstruktor bis zur geschlossenen Klammer durchlaufen werden? Ohne Thread würde dann ja der Konstruktor nie beendet werden.

Das mit den Maus/Tastatureingaben hab ich mir auch schon gedacht. Wäre das dann sozusagen der Thread für den Listener? Habe bis jetzt allerdings immer gedacht, dass für einen Maus/Key -Listener automatisch ein neuer Thread erstellt wird.


----------



## SlaterB (15. Sep 2010)

> dass für einen Maus/Key -Listener automatisch ein neuer Thread erstellt wird. 

nein

-----

der GameCanvas-Konstruktor würde nicht beendet werden, wenn man im Konstruktor die run-Methode mit der Endlosschleife aufruft,
ich habe da noch keinen richtigen Nachteil zu gesehen, wenn aber der main-Thread die Aufgabe übernehmen soll, dann sicherlich lieber


```
public static void main(String[] args) {
       GameCanvas g = new GameCanvas();
       g.run();
    }
```

ansonsten vom GameCanvas-Konstruktor aus einen neuen Thread starten, dann wird der Konstruktor auch beeendet,
der main-Thread hat danach nichts mehr zu tun, verläßt die main-Methode und wird bald beendet

soweit geklärt oder was genau war die Frage?


----------



## JavaException (17. Sep 2010)

Hi,
jup wäre dann geklärt. Danke für eure Hilfe


----------

