mrjerk: Neuen Thread Beispiel: Stoppuhr

Beitrag lesen

Hallo,

Wie funktioniert das mit einem Timer?? Ich möchte eine Art "zeitlinie" machen. Dh. Die Linie läuft von links nach rechts mit der zeit (zb. 100 px pro Sek.) aber wenn ich das mit dem abziehen mache habe ich ja nicht den genauen Wert jede ms oder nicht?

Wenn Du ständig die aktuelle Zeit abfragst, also in etwa so:

  
while (true) {  
   long actTime = System.currentTimeMillis();  
   // Tue irgendwas, z.b. Linie zeichnen  
}  

so hast Du den Nachteil, dass Du sehr viel CPU-Zeit damit verbrätst, immer und immer wieder durch die Schleife zu laufen. Besser ist es, ein bisschen zu warten, z.b. so:

  
while (true) {  
   long actTime = System.currentTimeMillis();  
   // Tue irgendwas, z.b. Linie zeichnen  
  
   try {  
       thisThread.sleep(200);  
   } catch (InterruptedException e){}  
  
}  

Jetzt macht Dein Programm nur noch alle 200ms was (in CPU-Zyklen eine halbe Ewigkeit, in der Zwischenzeit kann es von Betriebssystem "schlafen gelegt" werden, und andere Programme können laufen).
Es stimmt natürlich, Du hast damit (theoretisch) eine Art "Ruckeln" (= deine Linie wird nicht ständig aktualisiert, sondern eben nur alle 200ms) - bei ein paar 100ms ist das aber so wenig, dass es kaum ins Gewicht fallen dürfte - musst mal ein bisschen Rumspielen damit.

Eine andere Möglichkeit (und das ist glaube ich auch die, auf die Encoder anspielt), ist der Einsatz der Timer-Klasse, mit der kannst Du bestimmte Dinge zu einem bestimmten Zeitpunkt ausführen, oder zeitverzögert oder...
Aber wenn Du erstmal Threads kennenlernen willst, ist es ungünstig mit der Timer-Klasse anzufangen, denn die "Tasks", die Du damit steuerst, sind letztendlich widerrum Threads (somit solltest Du das Prinzip erstmal verinnerlicht haben).

Verfolgen wir also Deine ursprüngliche Idee weiter:
Du brauchst einen Thread, der die Uhrzeitanzeige übernimmt (Uhrzeit auslesen / Linie zeichnen /...). Hierzu musst Du für den Thread eine eigene Klasse schreiben, die das Interface "Runnable" implementiert. Damit dieser auch irgendwann wieder aufhört zu laufen, bekommt er einen "Stopp-Knopf" (siehe Methode "stopMe")

  
 class VisualizeTimeRunnable implements Runnable {  
         private boolean hasStopped = false;  
  
         // Konstruktor - Evtl. mit Parametern erweitern, die der Thread zum Ablaufen  
         // benötigt  
         public VisualizeTimeRunnable() {  
  
         }  
  
         public stopMe () {  
             this.hasStopped = true;  
         }  
  
         public void run() {  
             while (!hasStopped) {  
                long actTime = System.currentTimeMillis();  
                 // Tue irgendwas, z.b. Linie zeichnen  
                 try {  
                    thisThread.sleep(200);  
                 } catch (InterruptedException e){}  
  
             }  
         }  
}  

Dieser Thread kann jetzt von Deinem Hauptprogramm gestartet und selbstverständlich auch wieder gestoppt werden. Der Einfachheit halber lassen wir den Thread einfach mal starten, 5 Sekunden laufen und dann stoppen:

  
public static void main() {  
    VisualizeTimeRunnable clock = new VisualizeTimeRunnable();  
    Thread clockThread = new Thread(clock).start();  
    Thread.sleep(5000);  
    clock.stopMe();  
}  

Et voila! (Code nicht getestet, ohne Gewähr ;) ).

Du kannst natürlich schon irgendwas in einen Thread auslagern um Threads kennenzulernen. Aber da würde ich mir ein besseres Beispiel suchen.
Was für ein Beispiel empfiehlst du mir da?

Dein Beispiel kann man theoretisch auch in einem einzigen Thread abfrühstücken, ich finde es aber gar nicht so schlecht gewählt, um sich mal mit Multi-Threading zu befassen:
Ein Thread macht den ganzen Grafik/Anzeige-Schlonz, ein weiterer (also Dein Hauptprogramm) reagiert auf Benutzereingaben (in Deinem Fall "Start/stopp") - große GUIs machens de facto genauso.

Viel Erfolg beim ausprobieren.

Viele Grüße,
Jörg