Thread sofort beenden



  • Ich möchte einen Thread, den ich neu erzeugt habe beim Schließen des Fensters sofort beenden.

    So habe ich es gemacht:

    public class ViewDialog extends JFrame implements Runnable, WindowListener {
    
        /** Singleton implementation */
        private static ViewDialog _instance;
        public static synchronized ViewDialog getInstance(PartyShow parentFrame) {
            if (_instance==null)
            {
                _instance = new ViewDialog(parentFrame);
            }
            return _instance; 
        }
    
        /** Creates new form ViewDialog */
        private ViewDialog(PartyShow parentFrame) {
            //bla bla
            this.addWindowListener(this);
        }
    
        public void slideShow() {    
            this.show();
            th = new Thread(this, "ViewDialog");
            th.start();
        }
    
        public void run() {
            while(!th.isInterrupted())
            {
                //Zeug, das lange dauert.... Außerdem:
                this.repaintAndWait();
            }
        }
    
        private void repaintAndWait() {
            this.repaint();
            try
            {
                Thread.sleep(parent.getSleepTime()*1000);
            }
            catch (InterruptedException e)
            {
                th.interrupt();
            }
        }
    
        public void windowClosing(WindowEvent e) {
            th.interrupt();
        }
    
        Thread th;
     }
    

    In einer anderen Klasse wird das Ganze so gestartet:

    ViewDialog viewDialog = ViewDialog.getInstance(this);
    viewDialog.slideShow();
    

    Kann ich so erreichen, dass der Thread th beim Schließen des Frames ViewDialog sofort beendet wird? Wenn nicht, wie dann? Und wie kann ich feststellen, welche Threads denn gerade noch laufen?



  • Hi

    du must dir den Thread den du in slideShow anlegst merken. Weiter must du in deiner run Methode eine variable abfragen die du zum abbrechen verwendest. Die variable muss dan von ausen zugänglich sein, um den thread abbrechen zu lassen.

    kleines beispielimplementierung

    class MyThread extends Thread
    {
      private boolean running = false;
      private boolean go = true;
    
      // abfragen ob der thread noch laeft
      public boolean isRunning()
      {
        return running;
      }
    
      // den thread zum abbrechen bewegen
      public void stopThread()
      { 
        this.go = false;  
      }
    
      public void run()
      {
        running = true; // den thread als gestartet markieren
    
        while(go)
        {
           // irgend was machen....
        }
    
        running = false; // den thread als beendet markieren
      }
    }
    

    von ausen kanst du dann den thread so stoppen und überwachen.

    MyThread thread = new MyThread();
    
      // starten 
      thread.start();
    
      // dem thread mitteilen das er sich beenden soll
      thread.stopThread();
    
      // warten bis der thread auch wirklich sich beendet hat
      while(thread.isRunning())
      {
        Sleep(100); 
      }
    

    es gibt noch die möglichkeit über Thread.stop() zu arbeiten. nur ist das seit java 1.1 oder so debrekated und sollte nicht verewendet werden. da der thread hart abgebrochen wird und der zustand nicht vorhersagbar ist.

    gruss Termite



  • Wenn ich das richtig verstanden habe bleibt mein Problem aber das Gleiche:
    Ein Durchgang der While-Schleife kann u.U. seeehr lange dauern und wenn ich es so mache wie von Dir beschrieben, wird der Thread erst dann beendet, wenn die while-Schleife wieder mal ihre Bedingung prüft.

    Wenn nun ein Schleifendurchgang z.B. 5 Minuten dauert und ich nach 10 Sekunden das Fenster schließe, dauert es immer noch 4:50min, bis der Thread sich beendet.



  • Es gibt bei Threads die Methode stop(), die ist aber nicht zum Spaß deprecated. Du solltest dir lieber ein schlaueres System überlegen, wie du dem Thread sagst, dass er sich selbst beenden soll.



  • Optimizer schrieb:

    Es gibt bei Threads die Methode stop(), die ist aber nicht zum Spaß deprecated. Du solltest dir lieber ein schlaueres System überlegen, wie du dem Thread sagst, dass er sich selbst beenden soll.

    Deshalb frage ich ja. 😉



  • Hi

    das heist dann du must veruchen auch während des schleifendurchgnags abbrechen zu können.

    ggf must du dann schauen das du mehr in die Haupt schleife reinbekommst. bzw du must der Animation den Thread bekantmachen, und die animation prüft nach ob sie sich beenden soll. ist dies der fall, bricht sie ab anstelle zum nächten schritt zu gehen.

    im prinzip soetwas

    if (( go ) & ( Kriterium ))
    {
      // do next step
    }
    
    while (( go ) & ( Kriterium ))
    {
      // tu irgendwas
    }
    

    Ich hab selber schon die leidliche erfahrung gemacht, überall solche abbruch abfragen einbauen zu müssen.

    die andere möglichkeit über thread.stop() ist wie gesagt debrekeded. Bricht aber den thread sofort ab. Dabei wird weder auf offene netzwerkverbindunen noch auf dateien rücksicht genommen. Der Zustand der Applikation ist dadurch nicht vorhersagbar. Darum empfilt sun sich um das abbruchkriterium selber zu kümmern. ggf mit entsprechendem mehr aufwand.

    gruss Termite



  • Termite_ schrieb:

    debrekated

    Termite_ schrieb:

    debrekeded

    Soll'n wir hier Augenkrebs bekommen oder was?!? 😃



  • Wenn ein Thread gerade schläft, dann sollte er eigentlich sofort eine InterruptedException werfen, wenn du interrupt() aufrufst. Mancht er das nicht, dann ist was falsch. (nicht die richtige sleep-Methode oder so...)

    So ist es normalerweise jedenfalls kein Problem:

    public void run()
    {
      while (!isInterrupted()) {
        doSomething();
        try {
          sleep(mySleepTime);
        } catch (InterruptedException ex) {
          /* Dieser Teil hier sollte normalerweise eigentlich sofort
           * aufgerufen werden, wenn der Thread mittels interrupt beendet
           * wird und gerade schlief.
           */
          interrupt();
        }
      }
    }
    

    Dazu noch ein kleiner Auszug aus der APIDoc:

    //Beschreibung der Methode interrupt()
    If this thread is blocked in an invocation of the wait(), wait(long), or wait(long, int) methods of the Object class, or of the join(), join(long), join(long, int), sleep(long), or sleep(long, int), methods of this class, then its interrupt status will be cleared and it will receive an InterruptedException.

    Eventuell könnte auch ein th.join() was bringen, nachdem man den Thread mittels th.interrupt von 'außerhalb' beendet hat.


Anmelden zum Antworten