Advanced   Java   Services Deprecated Methoden, Threads beenden mit break, Dämonen Back Next Up Home


Deprecated: countStackFrames(), destroy(), resume(), stop(), suspend()

Die Klasse Thread gibt es seit der Version 1.0. Leider hat sich herausgestellt, daß obige fünf Methoden nicht immer fehlerfrei arbeiten (API: This method is inherently unsafe), deswegen sollte man diese Methoden nicht (mehr) verwenden. Man muß diese Funktionen selbst nachbilden. Statt die methode stop() zu verwenden wird in der API folgendes empfohlen:

Stopping a thread with Thread.stop causes it to unlock all of the monitors that it has locked
(as a natural consequence of the unchecked ThreadDeath exception propagating up the stack).
If any of the objects previously protected by these monitors were in an inconsistent state,
the damaged objects become visible to other threads, potentially resulting in arbitrary behavior.
Many uses of stop should be replaced by code that simply modifies some variable to indicate that
the target thread should stop running. The target thread should check this variable regularly,
and return from its run method in an orderly fashion if the variable indicates that it is to
stop running. If the target thread waits for long periods (on a condition variable, for example),
the interrupt method should be used to interrupt the wait.







Beenden mit break

Threads die quasi endlos laufen sind nichts unübliches, man nehme z.Bsp. einen Thread der in bestimmten Abständen den Status eines anderen Threads abfragt. Das kann man über Schleifen realisieren. Hier kann man eine Bedingung einbauen und prüfen, ob man die Schleife verlassen soll. Das wird mit dem folgenden Beispiel demonstriert.

public class MyRunnable implements Runnable
{
   private boolean running = true;

   @Override
   public void run()
   {
      int i=0;
      while(running)
      {
         System.out.println("runnin' " + ++i);
         // some work...
      }
      System.out.println("end run");
   }

   public void terminate()
   {
      running = false;
   }
}

Ein Mainprogramm startet den Thread und beendet ihn nach ca. 1 Millisekunde.

public class Main
{
   public static void main(String[] args)
   {
      MyRunnable runnable = new MyRunnable();
      Thread th = new Thread(runnable);
      th.start();
      try
      {
         Thread.sleep(1);  // eine millisekunde
         // oder seit Java 5 alternativ auch
         // TimeUnit.MILLISECONDS.sleep(1);
      }
      catch(InterruptedException ex)
      {
         ex.printStackTrace();
      }
      runnable.terminate();
   }
}

Bei dieser Variante wird der Thread immer nach einem vollendeten Schleifendurchlauf beendet.


Dämonen

Ein Thread muß keineswegs beendet sein, wenn der Mainthread endet. Threads können länger laufen als der Mainthread. Ein Programm ist erst dann zu Ende wenn auch der letzte von main aus gestartete Thread zum Ende gekommen ist. Man kann einen Thread aber so konfigurieren, daß er bei Programmende automatisch beendet wird. Dazu erzeugt man einen sog. Dämonthread, indem man vor dem Start des Threads die Methode setDaemon(boolean on) mit true aufruft. Die JVM beendet dann diesen Thread automatisch, wenn der letzte (Nichtdämon-) Thread sich beendet hat.

Das folgende Programm startet zwei Threads, einen Dämon und einen normalen Thread. Der normale Thread läuft nach Beendigung von main noch eine Weile. Der Dämonthread enthält eine Endlosschleife, wird aber trotzdem nach dem Ende des 'Nichtdämons' beendet.

public class Daemon extends Thread
{
   public Daemon()
   {
      this.setDaemon(true);
   }

   @Override
   public void run()
   {
      for(int i = 0; i>=0 ; i++)
      {
         System.out.println("damon");
         try
         {
            sleep(500);
         }
         catch(InterruptedException ex)
         {
            System.out.println(ex);
         }
      }
      System.out.println("end damon");
   }
}
public class NoDaemon extends Thread
{
   @Override
   public void run()
   {
      for(int i = 0; i < 5; i++)
      {
         System.out.println("no damon");
         try
         {
            sleep(1000);
         }
         catch(InterruptedException ex)
         {
            ex.printStackTrace();
         }
      }
      System.out.println("end nodamon");
   }
}
public class Main
{
   public static void main(String[] args)
   {
      Daemon daemon = new Daemon();
      NoDaemon noDaemon = new NoDaemon();
      daemon.start();
      noDaemon.start();
      System.out.println("end main");
   }
}

Das Programm macht in etwa die folgende Ausgabe. Man sieht sehr deutlich, daß der Dämon erst dann beendet wird, wenn der (letzte) von main aus gestartete Thread endet (nach "NoDaemon end" erfolgt keine weitere Ausgabe).

damon
no damon
end main
damon
no damon
damon
damon
no damon
damon
damon
no damon
damon
damon
no damon
damon
damon
end nodamon
Valid XHTML 1.0 Strict top Back Next Up Home