Threads Multithreading

Raikbit

Mitglied
Hallo Java-Gemeinde,

ich habe ein kleines Webdriver Projekt zusammengebastelt und nun würde ich es gern mittels Multithreading etwas kompfortabler gestalten.

Das Grundgerüst besteht aus 3 Klassen:
- GUI() mit diversen Buttons und einer LogFile Ausgabe
- Listeners() hält alle Listener der Buttons
- Handler() verbindet die GUI() mit den Listenern und hält den Webdriver

Im Moment ist es halt so ich starte den Handler und der ruft mir den Firefox und meine GUI auf.
Auf Knopfdruck wer hätte es gedacht soll nun was im Firefox passieren. Das funktioniert soweit ganz gut.

Mein Problem:
Wenn die Webseite mal hängt oder meine Routinen auf ein unerwartetes Problem stoßen, hängt sich das gesamte Programm auf. Somit nutzt mir die LogFile Ausgabe nix und ich habe auch keine Möglichkeit das Programm zu "unterbrechen".

Meine Idee:
Ich lasse alle 3 Klassen in extra Threads laufen. Wenn die Methode aus dem Listener festhängt, wäre dann die GUI nicht eingefroren und ich könnte dem Handler eine Abbruchmethode geben, welcher den aktuellen Listener stoppt und die Klasse Listeners clean neustartet.

Nun habe ich mich ein wenig belesen und komme einfach nicht weiter. Runnable und Thread ist für mich Neuland und die Standartbeispiele helfen mir nicht, weil ich demnach jede Methode in eine extra runnable Klasse schreiben müsste.

Gibt es nicht einen einfachen Weg meine Idee umzusetzen? ich habe bereits alle 3 Klassen in Threads umgewandelt (extends Thread). Nur irgendwie spreche ich die nun wahrscheinlich falsch an, da sich das Verhalten des Programms nicht geändert hat.
 

VfL_Freak

Top Contributor
Moin,

Gibt es nicht einen einfachen Weg meine Idee umzusetzen? ich habe bereits alle 3 Klassen in Threads umgewandelt (extends Thread). Nur irgendwie spreche ich die nun wahrscheinlich falsch an, da sich das Verhalten des Programms nicht geändert hat
der relevante Code wäre hilfreich ... rumraten möchte hier keiner ;)

Gruß Klaus
 

Raikbit

Mitglied
Code also ich versuch mal die relevanten Teile gemischt mit Pseudocode zum besseren Verständnis von dem was die Klassen machen.
Die GUI:
Java:
public class GUI extends Thread {
    private TuWas1
    private TuWas2
    private StopAlles3

    public GUI(){
         frame mit buttons und hübsch und so
    }
    public getters und setters für Buttons()
}
Die Listenters:
Java:
public class Listeners extends Thread{
    private Handler h;
    public Listeners(Handler h){
        this.h = h;
    }

    ActionListener ButtonTuWas1 = new ActionListener() {

         @Override
         public void actionPerformed(ActionEvent arg0) {
              h.getFirefox() und mache da tolle Sachen
        }
    };
    ActionListener ButtonTuWas2 = new ActionListener() {

         @Override
         public void actionPerformed(ActionEvent arg0) {
              h.getFirefox() und mache da andere tolle Sachen
        }
    };
}
Der Handler:

Java:
public class Handler extends Thread{
    private Webdriver firefox;
    private GUI gui;
    private Linteners lis;

    public Handler(){
        gui = new GUI();
        lis = new Listeners(this);

        gui.start();
        lis.start();

        gui.getTuWas1().addActionListener(lis.ButtonTuWas1);
        gui.getTuWas2().addActionListener(lis.ButtonTuWas2);
    }

   
    ActionListener ButtonStop = new ActionListener() {

         @Override
         public void actionPerformed(ActionEvent arg0) {
              lis.stop();
              lis.start();
        }
    };
}

Also wie ihr seht arbeite ich gar nicht mit runnables wo wahrscheinlich schon mein Denkfehler liegt. es ist auch irgendwie nur ein Thread aktiv zumindest friert die GUI immernoch ein solang eine Methode läuft. Aber vllt wird ja erkennbar was ich vorhabe und irgendwer kann mir den was Pseudocoden um mir klar zu machen wie es aussehen müsste damit es funktioniert.
 
Zuletzt bearbeitet von einem Moderator:

Joose

Top Contributor
Klassen erweitern heißt deren Funktionalität zu erweitern.

Wenn deine Klassen jeweils in einen Thread laufen sollen, heißt das nicht das es Threads sind bzw. deren Funktionalität erweitern. Daher ist diese Ableitung schon falsch.
Wie du selbst bemerkt hast solltest du wenn mit "Runnable" arbeiten.

Und die GUI selbst auslagern auf diese Art und Weise ist unnötig. Schau dir zu diesem Thema und dem einfrieren mal den SwingWorker und EDT an.
 

DrZoidberg

Top Contributor
Das ganze kann man sehr schön mittels ExecutorService lösen.
Einem ExecutorService kann man eine Reihe von Aufgaben geben, die er dann abarbeitet. Wobei er ein oder mehrere Worker Threads haben kann, auf die diese Aufgaben dann verteilt werden.

Hier mal ein Beispiel.
Es sind hier insgesamt 3 Threads im Spiel.
1. Der Thread, der von execMain verwaltet wird. Er dient dazu die meisten Aktionen des Programms auszuführen.
2. Der von execLog verwaltete Thread für Logging Zwecke.
3. Der "Event Dispatch Thread" wird von Swing automatisch erstellt und verwaltet. Alle GUI Aktionen (z.b. button clicks) laufen auf dem EDT.

Jede Änderung an der GUI, die nach dem ersten Anzeigen des JFrames stattfindet, muss im EDT passieren. Das kannst du erreichen mittels javax.swing.SwingUtilities.invokeLater.
z.B. SwingUtilities.invokeLater(() -> textField1.setText("neuer Text"))
Java:
import javax.swing.SwingUtilities;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ScheduledExecutorService;
import java.awt.event.ActionListener;
import static java.util.concurrent.TimeUnit.*;

public class Handler {
    private Webdriver firefox;
    private GUI gui;
    private Linteners lis;
    ExecutorService execMain = Executors.newSingleThreadExecutor();
    ScheduledExecutorService execLog = Executors.newSingleThreadScheduledExecutor();

    ActionListener ButtonStop = () -> {
      execMain.shutdownNow();
      execMain = Executors.newSingleThreadExecutor();
    };
 
    public Handler() {
      //...
      execLog.scheduleAtFixedRate(() -> updateLogFile(), 1, 1, SECONDS);
    }
}

public class Listeners {
    private Handler h;
    public Listeners(Handler h){
      this.h = h;
    }

    ActionListener ButtonTuWas1 = (e) -> h.execMain.submit(() -> {
      //h.getFirefox() und mache da tolle Sachen
    });
 
    ActionListener ButtonTuWas2 = (e) -> h.execMain.submit(() -> {
      //h.getFirefox() und mache da andere tolle Sachen
    });
}
 
Zuletzt bearbeitet:

Raikbit

Mitglied
Ok also vom Prinzip her is das genau das was ich gesucht habe .. nur leider immernoch mit dem Problem dass ich für jeden Listener eine Runnable Klasse erzeugen muss, da diese Form:

ActionListener ButtonTuWas1 = (e) -> h.execMain.submit(() -> {
//h.getFirefox() und mache da tolle Sachen
});

erst ab JAVA 1.8 funktioniert und ich zwingend in 1.7 arbeiten muss .. noch :(
aber ok ich probier das aus mit den Runnables und lass wieder von mir hören wenns funzt. Wird jetz halt mehr Arbeit als ich wollte :D
 

InfectedBytes

Top Contributor
in java 7 is das kaum mehr aufwand:
Code:
ActionListener al = new ActionListener() {
 public void actionPerformed(ActionEvent e) {
  // ...
 }
};
 

Raikbit

Mitglied
Hmm also so richtig machts nich das was es soll.

mein Listener sieht jetzt so aus:
Code:
ActionListener ButtonTuWas = new ActionListener() {
     
     @Override
     public void actionPerformed(ActionEvent arg0) {
       h.geteM().submit(new TuWas(h));
     }   
   };

startet also die Klasse TuWas implements Runnable

wenn ich nun aber den Stop Button betätige läuft der Prozess normal durch ... also weiß der shutdown Befehl nich was er beenden soll oder macht nich das was ich gern hätte :D

die Methode shutdownNow() verwirrt mich .. vom Namen her sehr gut aber gibt wohl nur ne Liste zurück welche Runnables in den shutdown gehen sollen .. ka liegen die dann auf sleep oder wie ist das zu verstehen .. bei mir ist diese Liste auch immer leer.
 

DrZoidberg

Top Contributor
Dann schreibst du stattdessen halt
Java:
ActionListener ButtonTuWas1 = new ActionListener() {
   public void actionPerformed(ActionEvent e) {
     h.execMain.submit(new Runnable() {
       public void run() {
         //h.getFirefox() und mache da tolle Sachen
       }
     });
  }
};
Ist ein wenig länger. Macht aber exact das selbe.
 

DrZoidberg

Top Contributor
shutdownNow gibt eine Liste der Runnables zurück, die sich noch in der Warteschlange befanden, also noch nicht gestartet wurden. Bei Runnables, die gerade laufen wird versucht sie zu beenden. Das funktioniert aber nur, wenn der Thread auf Thread.interrupt reagiert, was häufig nicht der Fall ist. Steht übrigens auch in der API Doku.

Ich frage mich wieso dein Programm ständig hängt, so dass du den Thread zwangsweise beenden musst. Falls das wirklich nötig sein sollte, kannst du es mit der kill() Methode in der FirefoxDriver Klasse versuchen. Es ist auch möglich Java Threads zu beenden, mittels Thread.stop(). Diese Methode ist zwar schon seit Jahren als deprecated markiert, funktioniert aber trotzdem. Dazu könntest du den ExecutorService über Executors.newSingleThreadExecutor(ThreadFactory threadFactory) erzeugen.
 
Zuletzt bearbeitet:

Raikbit

Mitglied
Naja sagen wir mal so mein WebDriver arbeitet in einer nicht so ganz stabilen Webseite welche ich selbst nicht ändern kann. Ist halt ein Arbeitsmittel für welches ich mir eine Arbeitserleichterung gebaut habe... wenn die Seite nun abstirbt hätte ich gern die Möglichkeit komplett auszusteigen und wenn die Seite sich refreshed hat wieder bei 0 einzusteigen ohne gleich das Programm neu starten zu müssen...

also wie ich nun rausbekommen habe ist es gewollt das der shutdown() den Task erst nach Beendingung abbricht, während der shutdownNow() an sich das macht was er soll .. er unterbricht aber nur die aktuelle Methode in meinem Listener, welcher aber aus einer Zusammensetzung von Methoden mit try and catch gebaut ist um Fehler in der Webseitenausführung zu vermeiden... somit läuft er in eine catch und macht dann mit der nächsten Anweisung weiter.

Lange Rede kurzer Sinn .. ich werds über stop() versuchen.
 

DrZoidberg

Top Contributor
Dann sollte dein Thread aber eine ClosedByInterruptException erhalten. Da können deine catch Anweisungen dann entsprechend drauf reagieren, bzw. ebend nicht reagieren.

Aber hast du es schon mit WebDriver.Timeouts versucht?
 

Raikbit

Mitglied
naja sagen wir mal so es ist nicht einfach nur das die Webseite abschmiert sondern auch manchmal Elemente nicht da hat wo sie sein sollten oder die äußeren Umstände ändern zwingend die Aktion welche mein Programm auslösen soll. Also Timeouts und so geschichten sind an sich abgefangen. Ich brauche halt wirklich zwingend die Hau Drauf Methode stop() um aktiv meine Methoden unterbrechen zu können.
 

DrZoidberg

Top Contributor
Ok. Aber ich habe trotzdem noch Zweifel, dass Thread.stop der beste Weg ist. Die FirefoxDriver Klasse müsste alles haben, was du brauchst. z.B. die quit() und startSession() Methode.
 

Raikbit

Mitglied
Bei webDriver.quit() beendet er aber die aktive Session und das ist gleichzusetzen mit ich muss das Programm neustarten. An sich macht mein Programm ja nix anderes als mich an verschiedenen Systemen anzumelden und dort je nach Button Arbeitsroutinen für mich auszuführen. Also dementsprechend ist der Webdriver ja schon zweckentfremdet da ich ihn nicht als Testumgebung sondern als Arbeitswerkzeug einsetze. Wie gesagt so ist es zwar nicht sauber programmiert aber es macht was es soll -> meine Arbeit leichter ;) Danke nochmal für die richtigen Schubser.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
buzzlightyeah multithreading Java Basics - Anfänger-Themen 4
sserio Frage zu Threading - Multithreading Java Basics - Anfänger-Themen 2
I Threads Multithreading, Producer/Consumer, notify() Java Basics - Anfänger-Themen 6
M Mehre Dateien parallel kopieren mit Multithreading Java Basics - Anfänger-Themen 8
kilopack15 Verzweiflung wegen Berechnung mit Multithreading Java Basics - Anfänger-Themen 1
P Multithreading in Java Java Basics - Anfänger-Themen 9
N Threads Read-Modify-Write Problem bei Multithreading (philosopher dining problem) Java Basics - Anfänger-Themen 5
Z Verständnisfrage zum Multithreading Java Basics - Anfänger-Themen 3
T Threads MultiThreading NullPointerException Java Basics - Anfänger-Themen 7
K Frage bzgl. Multithreading Java Basics - Anfänger-Themen 5
B Multithreading und eigene Queue entwickeln Java Basics - Anfänger-Themen 3
C Multithreading, Methoden sichern Java Basics - Anfänger-Themen 5
P Hilfe bei MultiThreading; Einige Fragen. Java Basics - Anfänger-Themen 14
S OOP Multithreading Java Basics - Anfänger-Themen 5
B Multithreading Java Basics - Anfänger-Themen 5
0din Multithreading und stop Java Basics - Anfänger-Themen 5
P Singletons und Multithreading Java Basics - Anfänger-Themen 11
U Anfängerfrage - Multithreading Java Basics - Anfänger-Themen 8
H Multithreading Java Basics - Anfänger-Themen 7
M Multithreading Java Basics - Anfänger-Themen 18
I Multithreading (Prüfungsvorbereitung) Java Basics - Anfänger-Themen 6
G UI friert bei Multithreading ein Java Basics - Anfänger-Themen 3
J Multithreading mit einer TextArea Java Basics - Anfänger-Themen 29
JFeel-x Multithreading in awt Java Basics - Anfänger-Themen 2
L NullpointerException wegen wahrscheinlichem Multithreading Java Basics - Anfänger-Themen 4
Z Multithreading Java Basics - Anfänger-Themen 2
P Multithreading Java Basics - Anfänger-Themen 22

Ähnliche Java Themen

Neue Themen


Oben