29.3 Das Interface  Runnable
 
Problem Mehrfach-vererbung Wir haben gelernt, dass wir eine Klasse X, in der wir einen nebenläufigen 'Prozess' laufen lassen wollen, am besten von Threads erben lassen. Ein Problem bekommen wir,  wenn unsere Klasse X bereits von einer Klasse, nennen wir sie A erbt. Wir hätten einen Fall von Mehrfachvererbung, was in Java nicht zulässig ist.
 

  Die Abbildung zeigt die Problematik. Eine Lösung bahnt sich an, wenn wir wissen, dass die Klasse Thread das Interface Runnable implementiert (siehe Bild unten)
 

  Das Interface Runnable ist sehr einfach gebaut. Seine Aufgabe besteht allein darin, zu garantieren, dass in den Klassen wie X die Methode run() tatsächlich implementiert wird. Aus diesem Grund implementiert auch die Klasse Threads selbst das Interface Runnable. Es hat die Gestalt:

public interface Runnable{
   public abstract void run();
}
 
  Der Ausweg besteht also darin, dass unsere Klasse X das Interface Runnable und damit die Methode run() implementiert und einem Thread-Objekt zur Kontrolle anvertraut (= übergeben) wird. Wir nützen dabei aus dass, die Klasse Thread einen Konstruktor besitzt, dem man eine Klasse vom Typ Runnable übergibt. Damit können die Anweisungen der in run() von X in einem nebenläufig ausgeführt werden. Unsere Lösung wird im Bild unten dargestellt.
 

Realisierung in einem Java-programm

Download:
X.java

public class X implements Runnable{
  public void run(){
    for (int i = 1; i<=10; i++){
      try{
        Thread.sleep((int)(Math.random()*10000));
        System.out.println(Thread.currentThread().getName()+": "+i);
      }
      catch(InterruptedException exp){
         return;
      }
    }
  }
}
  Der Einfachheit halber haben wir darauf verzichtet, X noch von einer anderen Klasse erben zu lassen. Die Methode run() sieht fast genauso aus, wie die  -Methode in der Klasse EigenerThread. Zum kleinen Unterschied: Da Runnable selber kein Thread ist, ist auch X kein Thread. Da sleep(...) eine Thread-Klassenmethode ist, muss jetzt Thread explizit benannt werden: Thread.sleep(...);. Bei der Klasse EigenerThread, die selbst ein Thread ist konnten wir darauf verzichten: sleep(...);
 
Download:
DemoX.java
public class DemoX{
   public static void main(String[] args){
      Runnable rs = new X();
      Runnable rt = new X();
      Thread s = new Thread(rs,"Thread Nr. 1");
      Thread t = new Thread(rt,"Thread Nr. 2");
      s.start();
      t.start();
   }
}
  In der Main-Methode werden zunächst zwei Instanzen der Klasse X erzeugt. Statt X rs = new X(); schreiben wir Runnable rs = new X(); was deshalb geht, weil X eine Unterklasse von Runnable ist. Anschließend werden zwei Threads-Objekte erzeugt, wobei wir den Konstruktor von der Klasse Threads (siehe Java-Dokumentation) benutzen, der es erlaubt, dem erzeugten Threads-Objekt das Objekt zu übergeben, das die nebenläufige Anweisungen enthält, also die run()-Methode enthält. Dieses Objekt muss vom Typ Runnable sein. Als zweiten Parameter übergeben wird den Namen, den unser Thread tragen soll. Schließlich werden die Threads aktiviert, also 'zum Leben erweckt'. Dies geschieht durch den Aufruf der start()-Methode, die die run()-Methode desjenigen Objektes aufruft, das das Thread-Objekt kontrolliert. Konkret heißt das: Die start()-Methode des Thread-Objekts s  das das Runnable-Objekt rs zur Kontrolle erhalten hatte, ruft die run()-Methode im Objekt rs auf. Somit gibt dieses Objekt rs auch "Thread Nr. 1" als den Namen des Thread-Objekts aus.
   
zu 29.4 Runnable als anonyme Klasse
zur Startseite www.pohlig.de  (C) MPohlig 2006