Announcement

Collapse
No announcement yet.

Thread Stoppen - wie mache ich das richtig?

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Thread Stoppen - wie mache ich das richtig?

    <B>thread.Stopp();</B><BR>
    gibt Warnung an: "method Stop() wurde abgelehnt"

  • #2
    Hallo Andreas,

    ein Thread der mit stop() beendet wurde kann das Objekt auf dem er gearbeitet hat in einem inkonsistenten Zustand verlassen - daher die Deprecation. Näheres auch in der Doku bzw im Tutorial. Wenn der Zustand - also der Informationsinhalt - eines solchen Objektes nach dem Aufruf von stop() nicht mehr weiterverarbeitet wird, dann kannst du die Methode weiterhin benutzen.

    Andernfalls ist das Stoppen am besten mit einer Kombination aus einem booleschen Flag und der Methode interrupt() zu bewerkstelligen.

    Arbeitet ein Thread auf einem Objekt in einer while - Schleife, dann
    kann die Beendigung durch das Flag durchgeführt werden:
    volatile boolean running = true;

    <pre>
    while(running == true)
    {
    aObject.doSomething();
    }
    </pre>
    Wenn die Arbeit beendet werden soll, dann das Flag einfach auf false setzen (while ist in der run() Methode des Threads).
    Die Methode interrupt() bringt hier nichts, die Schleife wird nicht beendet.

    Wenn aber in der Methode doSomething wait() bzw. sleep() aufgerufen werden, dann verursacht der Aufruf von interrupt() eine InterruptedException. Diese reichst du durch erneutes Werfen an die run() Methode weiter die sich ihrerseits beendet.

    <pre>
    try
    {
    while(running == true)
    {
    aObject.doSomething();
    }
    }
    catch (InterruptedException ex)
    {
    }
    </pre>

    Wenn du hier running == false setzt und der Thread durch wait() oder sleep() pausiert, dann wird die Schleife erst beendet wenn der Thread zurückkehrt - durch den Aufruf von interrupt() hingegen sofort.
    <br>
    Also könnte die stop Methode so aussehen
    <pre>
    public void stopMe()
    {
    running == false;
    interrupt();
    }
    </pre>

    Thoma

    Comment


    • #3
      Hi Thomas,<BR>
      erst DANKE!<BR>
      aber wieso funktioniert mein Beispiel nicht?<BR>

      <B>Hier mein Source:</B>

      <PRE>
      import java.awt.*;
      import java.awt.event.*;
      import javax.swing.*;

      public class Frame extends JFrame {
      FlowLayout flowLayout1 = new FlowLayout();
      JButton button1 = new JButton("START");
      JButton button2 = new JButton("STOP");

      MainThread mThread = new MainThread();

      public Frame() {
      this.getContentPane().setLayout(flowLayout1);

      //Thread - START -
      button1.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
      mThread.running = true;
      mThread.start();
      }
      });

      //Thread - STOP -
      button2.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
      mThread.running = false;
      mThread.interrupt();
      }
      });

      this.getContentPane().add(button1, null);
      this.getContentPane().add(button2, null);
      }

      public static void main(String[] args) {
      Frame frame = new Frame();
      frame.setSize(200, 100);
      frame.setVisible(true);
      }
      }

      //Thread Class
      class MainThread extends Thread {

      boolean running;

      public void run() {
      while(running) {
      meineMethode();
      }
      }

      private void meineMethode() {
      for(int i=0; i<10000; ++i )
      { System.out.println(i); }
      }
      }
      </PRE&gt

      Comment


      • #4
        Hallo Andreas,

        dein Beispiel funktioniert schon. Da du aber in while wieder eine Schleife startest, wird running erst geprüft wenn die for Schleife beendet ist.

        Ausserdem running öffentlich machen ist nicht gerade objektorientiert.
        interrupt() bringt in diesem Beispiel eh nichts.

        Thoma

        Comment


        • #5
          Hi Thomas,<BR>
          dank deines Tipps funktioniert fast alles.<BR>
          Zwei fragen noch:<BR>
          <B>1.</B> Wie kann der Start-Button deaktiviert werden, während der Thread aktiv ist (mit isAlive funktioniert diese Abfrage nicht)<BR>
          <B>2.</B> Wie kann ich diesen Thread nach dem Abbruch, wieder von vorne starten.<BR>

          <B>Source:</B><BR>
          <PRE>

          //Thread - START -
          //
          button1.addActionListener(new java.awt.event.ActionListener() {
          public void actionPerformed(ActionEvent e) {
          mThread.anfang = 0;
          mThread.ende = 10000;
          mThread.running = true;
          mThread.start();
          }
          });
          //
          //Thread - STOP -
          //
          button2.addActionListener(new java.awt.event.ActionListener() {
          public void actionPerformed(ActionEvent e) {
          //Thread abfrage
          if(mThread.isAlive()) {
          mThread.ende = +1;
          mThread.running = false;
          System.out.println("Thread -STOP-");
          }
          }
          });
          //
          //-------------------- Thread Class --------------------
          //
          class MainThread extends Thread {

          boolean running;
          int anfang;
          int ende;
          int i;
          //
          public void run() {
          while(running) {
          meineMethode();
          }
          }
          //
          public void meineMethode() {
          for(i=anfang; i<ende; ++i)
          { System.out.println(i); }
          running = false;
          }
          }

          </PRE&gt

          Comment


          • #6
            Zu 1:

            entweder über eine Überwachungsthread - das ist ein wenig komplizierter, oder du schreibst einfach button1.setEnabled(false)
            nach mThread.start();

            In deinem Stop Listener schreibst du dann button1.setEnabled(true)

            Zu 2:

            Du musst den Thread mit new neu erzeugen. Sobald run() beendet wird,
            ist der Thread beendet. Wenn du ihn nur pausieren lassen willst, dann
            musst du mit wait() und notify() oder auch mit sleep() arbeiten.

            isAlive() zeigt nur an dass der Thread schon gestartet wurde.

            Thoma

            Comment


            • #7
              Hallo Thomas,<BR>
              Danke!!!<BR>
              endlich habe ich das Thema im Griff. :-

              Comment

              Working...
              X