28.2 Eine eigene Thread-Klasse
 
  Um Ausführungen eines Programms nebenläufig, also parallel zueinander ausführen zu können, bringt man sie in Klassen unter die selbst einen Thread darstellen. In Java ist dies leicht zu realisieren. Man lässt seine Klasse von der fertigen Klasse Threads erben und überschreibt die von Thread geerbten Methode run(). In dieser Methode bringt man die Anweisungen unter, die später nebenläufig abgearbeitet werden sollen. Im Bild der Perlenschnur sind dies die Prozesse, die nacheinander abgearbeitet und vom Thread kontrolliert werden

 

Download:
EigenerThread. java
public class EigenerThread extends Thread{
   public void run(){
      for (int i = 1; i<=10; i++){
         try{
            sleep((int)(Math.random()*10000));
            System.out.println(getName()+": "+i);
         }
         catch(InterruptedException exp){
            return;
         }
      }
   }
}
  In der run()-Methode implementieren wir eine Schleife, in der bei jedem Durchgang die Klassenmethode sleep(int millis) aufgerufen wird. Diese Methode hat EigenerThread von Thread geerbt. Wird sie ausgeführt, so wird der Thread, der die run()-Methode kontrolliert für eine gewisse Zeit angehalten. Die 'Schlafdauer' wird der Methode in Millisekunden übergeben. Beim Aufruf in unserer Schleife übergeben wir der Methode sleep(...) eine Zufallszahl. Beim Ausführen der Methode kann es zu einer Ausnahme kommen, weshalb eine try-catch Konstruktion implementiert werden muss. Im try-Block implementieren wir die 'eigentliche' Funktionalität von run(). Im Block der catch(...)-Methode bringen wir das unter, was getan werden soll, falls sleep(...) eine Ausnahme auslöst. Eine solche Ausnahme liefert ein Objekt des Typs InterruptedException, deshalb muss catch ein Objekt vom Typ InterruptedException übergeben werden können.
Der Einfachheit halber, wird im Ausnahmefall nichts passieren.

 

Download:
EigenerThread Demo.java
Um die eigene Threadklasse zu testen, benutzen wir ein Demoprogramm, in der zwei Instanzen unserer selbstgeschriebenen Threadklasse benutzt. 
public class EigenerThreadDemo{
   public static void main(String[] args){
      EigenerThread s = new EigenerThread();
      EigenerThread t = new EigenerThread();
      s.start();
      t.start();
   }
}
 

Der rote Faden im Bild rechts stellt den Thread dar, der die main()-Methode der Demiklasse kontrolliert. Mit

EigenerThread s =
           new
EigenerThread();
EigenerThread t =
           new
EigenerThread();

werden zwei neue Threads (blaue Fäden) erzeugt. Aber erst mit dem Aufruf der start()-Methode für die beiden Thread-Objekte werden die Prozesse, die sie kontrollieren sollen, gestartet. Um einen Thread zu starten, benutzt man die von Thread geerbte Methode start(). Diese Methode organisiert den Thread und ruft dabei auch seine run()-Methode auf, in der, wie wir wissen, die Prozesse implementiert sind, die vom Thread kontrolliert abgearbeitet werden soll,


Die Methode
getName() liefert den Namen des Threads. Dieser Name wurde beim Erzeugen des Threads mit Hilfe des Standardkonstruktors generiert1). Das linke untere Bild zeigt diese 'Standardnamen'. Um 'seinem' Thread einen selbtgewählten Namen zu geben, benutzt man einen anderen Konstruktor der Klasse Thread.

  Dann aber reicht der Standardkonstruktor der Klasse EigenerThread nicht mehr aus. Wir müssen ihn implemeniteren: Er wird so angelegt, dass den richtigen Konstruktorvon der Klasse Thread aufruft. Das Ergebnis zeigt das rechte Bild (Quelltext siehe unten)

 

neuer Konstruktor von EigenerThread
public EigenerThread(String name){
      super(name);
}
Modifikation im Demo
EigenerThread s = new EigenerThread("Thread t");
EigenerThread t = new EigenerThread("Thread s");

 

Neue Ausgabe

Download: (Vers. 2)
EigenerThread. java
EigenerThread Demo.java

Die Ausgabe zeigt, dass nicht nur die Namen anders ausgegeben werden, sie zeigt auch, dass das erneute Starten der Demo auch die Reihenfolge, in der die Thread 'zu Wort' kommen unterschiedlich ist, dass es sich also tatsächlich um nebenläufige Prozesse handelt.

Starten wir den Windows-Task-Manager und danach unser EigenerThreadDemo, so zeigt sich im unter der Rubrik Prozesse der Interpreter  java.exe mit 10 Threads. Zwei davon sind die von uns programmierten, wir erkennen dies daran, dass die Zahl der Threads auf 9 sinkt, wenn einer der selbstprogrammierten Threads fertig ist, 'seine Schleife' also den Zähler 10 erreicht und ausgegeben hat.
   
 
 
Fußnoten  

1)

Will man genauer verstehen was, hier passiert, muss man wissen, dass bei der Instanziierung von EigenerThread automatisch der Standardkonstruktor EigenerThread() aufgerufen wird. Dieser Standardkonstruktor, den man, wie wir früher gesehen haben, nicht zu implementieren braucht, ruft seinerseits den Standardkonstruktor Thread() der Klasse Thread auf. Dieser Konstruktor nun ist verantwortlich für die implizite Namensgebung.

Wir hätten also in der Klasse EigenerThread folgenden Konstruktor schreiben können:

public EigenerThread() {
  super();
}

Der Aufruf super(); ruft den Konstruktor Thread() auf, die API informiert:

public Thread()
Allocates a new Thread object. This constructor has the same effect as Thread(null, null, gname), where gname is a newly generated name. Automatically generated names are of the form "Thread-"+n, where n is an integer.

[zurück]

zu 28.3 Das Interface Runnable
zur Startseite www.pohlig.de  (C) MPohlig 2006