71. Thread & Runnable

Die main() Methode ist lediglich ein Thread.

Möglichkeit 1: Klasse Thread (nicht so gut)

  • Ein neuer Thread wird in Java über Thread-Objekte erzeugt (Klasse Thread)

  • Die Thread.run() Methode erzeugt einen neuen Thread: leerer Rumpf

  • run() Methode muss überschrieben werden

    public class MyTask extends Thread{
    
        @Override
        public void run(){
            //Code für den zusätzlichen Thread
        }
    }
    
  • Die start() Methode erzeugt einen neuen Thread (asynchrone Methode)

    1. Ein neuer Systemthread wird erzeugt

    2. In diesem wird die run() Methode aufgerufen

    3. Direkt danach wir die start() Methode wieder verlassen und die main() Methode läuft parallel zur run() Methode

    MyTask t = new MyTask();
    t.start();
    
  • Ein Thread kann in einer Instanz nur ein Mal gestartet werden

  • Zum erneuten Aufrufen der run() Methode muss eine neue Instanz erzeugt werden

Hint

Mit Thread.sleep(long millies) wird der Prozess für x Millisekunden pausiert.

  • Ein Multi-Thread Program stürzt erst dann ab wenn kein Thread mehr läuft

  • Es stürzt nicht automatisch mit dem Absturz der main() Methode ab

  • Wie die Threads eines Programm auf die CPU-Kerne verteilt werden liegt in der Hand des Schedulers (wir haben darauf keinen Einfluss)

  • In der Praxis sollten nicht zu viele Threads parallel existieren

  • Es ist nicht wichtig wo im Program neue Threads erzeugt werden

Möglichkeit 2: Interface Runnable (Unbedingt vorzuziehen!!!)

  • Besitzt nur die run() Methode

  • Die Klasse Thread implementiert diese run() Methode:

    public class MyTask implements Runnable{
    
  • Um Methoden der Thread Klasse zuzugreifen wird die Instanzmethode Tead.currentThread()hr verwendet:

    Thread.currentThread().getName()
    
  • Der Rest in the Klasse bleibt gleich

  • In der main() Methode wird der Zugriff auf die start() Methode über das Erzeugen eines neuen Thread Objektes ermöglicht, welcher eine Runnable als Übergabeparameter akzeptiert:

    MyTask t = new MyTask();
    Thread thread = new Thread(t);
    thread.start();
    
  • Es wird die start() Methode der übergebenen Runnable ausgeführt (nicht die Thread.start() Methode)

  • Vorteil: Die Implementierung von einem Interface ist stets möglich, jedoch gibt es keine Mehrfachvererbung in Java (deadly diamond of death). Somit kann eine Klasse die bereits eine Klasse beerbt nicht mehr von der Klasse Thread erben

Thread beenden (bevor die run() Methode abgeschlossen ist)

Falscher Weg:

  • Thread.stop() Methode

  • Die Methode ist veraltet (deprecated)

Richtiger Weg: Sauberes Beenden des Threads durch eine Bedingung in der Thread-Klasse, welche eine Variable verändert und damit das Beenden des Threads hervorruft:

  1. Initialisierung eines boolean Wertes private boolean alive;

  2. Bedingung in die run() Methode schreiben, welche die Methode durch return beendet sobald der boolean false ist:

    if(!alive ){
    System. out.println("Stopping!" );
      return;
    }
    
  3. Eine Methode definieren, welche die Variable verändert:

    public void cancel(){
        alive = false;
    }
    
  4. Die Abbrechmethode (hier: cancel()) wird vom den Thread aufrufenden Thread aufgerufen: t.cancel();

Hinweise zum Verwenden von neuen Threads:

  • keinen neuen Thread für kleine Berechnungen

  • für Dinge, die im Hintergrund laufen sollen (z.B. regelmäßiges Abgleichen von Daten)

  • zu viele Threads überlasten den Rechner wegen des Scheduling (Geschwindigkeitsgewinn geht zurück)