Anzeige:
Ergebnis 1 bis 13 von 13

Thema: Java: GUI + 2 Threads

  1. #1
    Registrierter Benutzer
    Registriert seit
    11.09.2000
    Ort
    Schweiz
    Beiträge
    142

    Java: GUI + 2 Threads

    Hallo mal wieder...

    Ich habe 2 Threads. Im ersten Thread läuft die Applikation mit GUI. Im 2. Thread werden prozessorintensive Funktionen gestartet. Wie kann ich jetzt verhindern dass das GUI völlig blockiert wird? Ich habe mal folgendes versucht:

    Code:
    		Thread thrd = new Thread(this);
    		thrd.start();
    		
    		while (thrd.isAlive())
    		{
    			try
    			{
    				Thread.sleep(100);
    				this.paintComponents(this.getGraphics());
    			}
    			catch (InterruptedException ie){}
    		}
    Die funktioniert, kann aber nicht die beste Lösung sein, oder?

  2. #2
    Registrierter Benutzer Avatar von bischi
    Registriert seit
    10.04.2003
    Beiträge
    4.828
    Also wenn ich richtig verstanden habe:

    Thread 1: GUI
    Thread 2: Berechnungen

    Die GUI sollte jetzt eigentlich überhaupt nicht mehr blockiert sein, selbst wenn Thread2 zugespammt ist. Was du machst, ist, dass du nicht im neuen Tread wartest, sondern im Hauptthread (der mit der GUI). Mit Thread.sleep(100) und den anschliessenden Befehlen wartest du im Hauptthread 100ms um dann etwas neu zu zeichnen. Den neuen Thread beachtest du mit deinem Code gar nicht mehr, nachdem du ihn mal erzeugt hast.

    Zum Thema Threads kann ich auf jeden Fall www.javabuch.de empfehlen; Einfach runterladen (gratis) und in Kapitel22 nachsehen, wies geht (musst wohl oder übel eine neue Klasse machen afaics).

    MfG Bischi

    "There is an art, it says, or rather, a knack to flying. The knack lies in learning how to throw yourself at the ground and miss it" The hitchhiker's guide to the galaxy by Douglas Adams

    --> l2picfaq.pdf <-- www.n.ethz.ch/~dominikb/index.html LaTeX-Tutorial, LaTeX-Links, Java-Links,...

  3. #3
    Registrierter Benutzer
    Registriert seit
    11.09.2000
    Ort
    Schweiz
    Beiträge
    142
    Yep, funktionieren tut es ja, nur wird durch die ewige Abfragerei im ersten Thread etwas Leistung verschenkt. Das GUI muss nicht wirklich benutzbar sein, es soll nur nicht so aussehen wie wenn die Applikation eingefroren wäre.

  4. #4
    Registrierter Benutzer Avatar von peschmae
    Registriert seit
    14.03.2002
    Ort
    Schweizland
    Beiträge
    4.549
    @itsme: Das was du da macht ist irgendwie zwischen zwei Welten.

    Grundsätzlich hat man zwei weit verbreitete Möglichkeiten das responsivitätsproblem in Apps bei langen Operationen zu umgehen:

    1) Man sorgt während den Operationen dafür (alles in einem Thread) dass regelmässig der Eventloop abgearbeitet wird - u.A. kommt damit auch das Neuzeichnen der Fenster

    2) Man macht Threads - d.h. der eine Thread läuft im Hintergrund und die kommunizieren dann über irgendwelche Signale (z.B. synchronized Variablen oder was auch immer)

    Was du hier machst ist du machst einen Thread der im Hintergrund läuft 2) aber dann lässt du den ersten Thread nicht einfach sein sondern "sperrst" ihn wie aus 1) in eine lange Operation ein (hier ne Schleife mit sleep und neuzeichnen) und lässt ihn hauptsächlich warten und n bisschen Zeichnen.

    Wie du das mit Swing-Guis am elegantesten löst weiss ich nicht. Hab sowas nie gemacht. Ein Problem könnte hier werden dass Swing den Eventloop normalerweise vor dir "versteckt" - das Zeugs ist im geheimen schon Multithreaded.

    Die "richtige Richtung" wäre dass du z.B. beim Klick auf Start den Hintegrundrechnungsthread startest und den laufen lässt. Also:
    Code:
    Thread thrd = new Thread(this);
    thrd.start();
    der Thread "weiss" selber am besten wann er wie weit ist (Statusmeldung?) oder wann er fertig ist und löst dann die entsprechenden Ereignisse aus.

    MfG Peschmä
    The greatest trick the Devil ever pulled was convincing the world he didn't exist. -- The Usual Suspects (1995)
    Hey, I feel their pain. It's irritating as hell when people act like they have rights. The great old one (2006)

  5. #5
    Registrierter Benutzer Avatar von bischi
    Registriert seit
    10.04.2003
    Beiträge
    4.828
    Yep, funktionieren tut es ja, nur wird durch die ewige Abfragerei im ersten Thread etwas Leistung verschenkt. Das GUI muss nicht wirklich benutzbar sein, es soll nur nicht so aussehen wie wenn die Applikation eingefroren wäre.
    Machst du aber - hab ich dir versucht, zu erklären: Ich nehme mal an, du hast eine Klasse (nennen wir die Test), die von einer anderen Klasse (AWT oder Swing) ein Fenster erbt. Du wirst wohl im Konstruktor (Test() {...}) deine GUI zeichnen und dann deine Schleife aufrufen. Damit verhinderst du aber, dass der ganze Konstruktor abgearbeitet werden kann und dein Programm auf Nachrichten reagieren kann - das Programm (also die GUI) "friert" ein. Egal was du machst - die GUI kann nicht auf Nachrichten (Eingaben, Klicks,...) reagieren.

    Wie du es richtig machen musst (neue Klasse erstellen, die von Thread erbt und die berechnungen durchführt) und wie du alles miteinander verknüpfen musst, steht ausführlich (und relativ lang) im www.javabuch.de im Kapitel 22.

    MfG Bischi

    "There is an art, it says, or rather, a knack to flying. The knack lies in learning how to throw yourself at the ground and miss it" The hitchhiker's guide to the galaxy by Douglas Adams

    --> l2picfaq.pdf <-- www.n.ethz.ch/~dominikb/index.html LaTeX-Tutorial, LaTeX-Links, Java-Links,...

  6. #6
    Registrierter Benutzer Avatar von peschmae
    Registriert seit
    14.03.2002
    Ort
    Schweizland
    Beiträge
    4.549
    Aus dem Thread raus Gui-Sachen manipulieren geht bei Swing übrigens ganz ähnlich wie bei SWT - habs eben mal nachgeguckt.

    Du machst ne Klasse die "Runnable" implementiert und den Code enthält, den du aus dem nicht-Gui Thread heraus ausführen willst (und der die Gui manipuliert)
    Code:
    public class Updater implements Runnable {
      String wichtigesArgument;
      public Updater(String wichtigesArgument) {
        this.wichtigesArgument = wichtigesArgument;
      }
      
      public void run() {
        label.setText(wichtigesArgument);
      }
    }
    dann tust du im Rechnungsthread sowas ausführen:
    Code:
    Runnable updater = new Updater("mein extrem wichtiger neuer TExt für das Olle label");
    EventQueue.invokeLater(updater);
    alternativ gibts auch EventQueue.invokeAndWait() - das wartet im Hintergrundthread dann so lange bis der Gui-Thread das Zeugs ausgeführt hat.

    MfG Peschmä
    The greatest trick the Devil ever pulled was convincing the world he didn't exist. -- The Usual Suspects (1995)
    Hey, I feel their pain. It's irritating as hell when people act like they have rights. The great old one (2006)

  7. #7
    Registrierter Benutzer Avatar von bischi
    Registriert seit
    10.04.2003
    Beiträge
    4.828
    Oder so was (Beispiel aus www.javabuch.de übernommen):

    Code:
    001 /* Listing2201.java */
    002 
    003 class MyThread2201
    004 extends Thread
    005 {
    006   public void run()
    007   {
    008     int i = 0;
    009     while (true) {
    010       System.out.println(i++);
    011     }
    012   }
    013 }
    014 
    015 public class Listing2201
    016 {
    017   public static void main(String[] args)
    018   {
    019     MyThread2201 t = new MyThread2201();
    020     t.start();
    021   }
    022 }
    MfG Bischi

    "There is an art, it says, or rather, a knack to flying. The knack lies in learning how to throw yourself at the ground and miss it" The hitchhiker's guide to the galaxy by Douglas Adams

    --> l2picfaq.pdf <-- www.n.ethz.ch/~dominikb/index.html LaTeX-Tutorial, LaTeX-Links, Java-Links,...

  8. #8
    Registrierter Benutzer
    Registriert seit
    15.09.2003
    Beiträge
    10
    so wie es peschmae beschrieben
    hat, (mit dem interface Runnable) muss man es
    unbedingt machen bei swing, da dort nicht alle
    klassen threadsicher sind....


    dort ist's ziemlich gut erklaert:
    http://www.javaworld.com/javaworld/j...ingworker.html

    ausserdem google mal nach SwingWorker - diese klasse erleichtert
    so einiges....

  9. #9
    Registrierter Benutzer Avatar von bischi
    Registriert seit
    10.04.2003
    Beiträge
    4.828
    Spielt afaics absolut keine Rolle, wenn du synchronized-Variabeln zum Daten übermitteln brauchst.

    MfG Bischi

    "There is an art, it says, or rather, a knack to flying. The knack lies in learning how to throw yourself at the ground and miss it" The hitchhiker's guide to the galaxy by Douglas Adams

    --> l2picfaq.pdf <-- www.n.ethz.ch/~dominikb/index.html LaTeX-Tutorial, LaTeX-Links, Java-Links,...

  10. #10
    Registrierter Benutzer
    Registriert seit
    15.09.2003
    Beiträge
    10
    @bischi:

    genau, dass ist ja das problem, swing benutzt intern eben
    keine solchen 'synchronized variablen'....

    solange du in einem 2. thread nur berechnest ist alles gut...
    wenn du aber eine gui hast, willst du frueher oder spaeter auch
    irgendein ergebnis 'sehen'

    wie zb. im obigen beispiel setText("bla bla")....

    mach das mal mit 2 oder mehr threads aufs selbe objekt
    und es wird knallen..... ;-)

  11. #11
    Registrierter Benutzer Avatar von bischi
    Registriert seit
    10.04.2003
    Beiträge
    4.828
    Hab selber gerade eben was gebastelt und mein Problem glaub ich gefunden:

    an run() kann man keine Argumente übergeben - sonst wäre das ganze überhaupt kein Problem.

    MfG Bischi

    "There is an art, it says, or rather, a knack to flying. The knack lies in learning how to throw yourself at the ground and miss it" The hitchhiker's guide to the galaxy by Douglas Adams

    --> l2picfaq.pdf <-- www.n.ethz.ch/~dominikb/index.html LaTeX-Tutorial, LaTeX-Links, Java-Links,...

  12. #12
    Registrierter Benutzer Avatar von peschmae
    Registriert seit
    14.03.2002
    Ort
    Schweizland
    Beiträge
    4.549
    Original geschrieben von bischi
    Spielt afaics absolut keine Rolle, wenn du synchronized-Variabeln zum Daten übermitteln brauchst.
    Daten übermitteln ja. Aber wenn du z.B. was an der GUI ändern willst (e.g. ProgressBar, Ergebnisanzeige, was weiss ich) dann geht das mit synchronized Variablen nicht mehr wirklich praktisch.

    MfG Peschmä
    The greatest trick the Devil ever pulled was convincing the world he didn't exist. -- The Usual Suspects (1995)
    Hey, I feel their pain. It's irritating as hell when people act like they have rights. The great old one (2006)

  13. #13
    Registrierter Benutzer Avatar von bischi
    Registriert seit
    10.04.2003
    Beiträge
    4.828
    Hab das Problem gesehen - Peschmäs Lösung scheint die am wenigsten komplizierte zu sein.

    MfG Bischi

    "There is an art, it says, or rather, a knack to flying. The knack lies in learning how to throw yourself at the ground and miss it" The hitchhiker's guide to the galaxy by Douglas Adams

    --> l2picfaq.pdf <-- www.n.ethz.ch/~dominikb/index.html LaTeX-Tutorial, LaTeX-Links, Java-Links,...

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •