Ist Background-Threading in Java wirklich so schwer?

Thallius

Top Contributor
Hi,

ich komme aus der OSX Ecke und wenn ich dort etwas mache, dass im Hintergrund ausgeführt werden muss weil es zu lange dauert, dieses aber gleichzeitig das UI verändern muss, dann geht das ungefähr so:

Code:
-void methodeXYirgendeinerKlasse()
{
    // Öffne ein Fenster (Meinetwegen ProgressIndikator)
    [self.performSelectorInBackground:@selector(backgroundMethode:) withObject:irgendeinObject];
}

-(void)backgroundMethode:(IrgendEinObject)irgendeinObject
{
    do
    {
        // mache halt irgendwas
        [self.performSelectorInMainThread:@selector(updateMainMethode:) withObject:irgendeinObject];
    }
    while()
    [self.performSelectorInMainThread:@selector(doneMainMethode:) withObject:irgendeinObject];
}

-(void)updateMainMaetohde:(IrgendeinObject)irgendeinObject
{
    // refreshen wir das ProgressBar
}

-(void)doneMainMaetohde:(IrgendeinObject)irgendeinObject
{
    // Schließen wir das Fenster und machen weiter mit unserem Programm....
}

Das ist alles.

Jetzt versuche ich gerade sowas profanes mit Swing hinzubekommen. Ich dachte ok, wird nicht so schwer sein. Aber Pustekuchen. Ich habe es erst mit einem einfach runnable mit einem Thread versucht und dann nach dem Thread.start() direkt einen Thread.join(), damit der Maintask schonmal darauf wartet das der Hintergrund Thread fertig wird. Dummerweise scheint er den Thread start aber wohl zu machen bevor das setVisible() von meinem ProgressPanel komplett ausgeführt wurde. Jedenfalls erscheint da ein leeres Frame auf dem Bildschirm. Ok, dann versuche ich es halt mit dem SwingUtilities und InvokeLater. Nun habe ich mein ProgressFrame aber dafür rennt mein Mainthread direkt durch und schließt das ProgressFrame direkt wieder....

Das kann doch nicht so kompliziert sein so etwas zu machen. Alle Tutorials dazu sind erschreckend unverständlich für mich. Wahrscheinlich weil ich einfach ganz anders denke oder finde ich einfach nicht das richtige?

Gruß

Claus
 

Tobse

Top Contributor
Da wäre einmal die Klasse SwingWorker, das wäre best Practice. Ich mache es aber in fast allen Anwendungen so:

Java:
interface ProgressListener
{
     public void processStarted(int min, int max);
     public void processStateChanged(int value);
     public void processStateIncreased(); // wenn mehrere Threads arbeiten
     public void processFinished();
}

class ProgressFrame extends JFrame
{
    public void setMinimum(int min); // wird weitergegeben an eine JProgressBar
    public void setMaximum(int max); // wird auch weitergegen an eine JProgressBar
    public void processStateChanged(int value); // und auch hier an die JProgressBar
    public void setIndeterminate(boolean is); // und das auch an die JProgressBar
}

class DoSomething
{
    public void doSomething()
    {
        ProgressFrame pFrame = new ProgressFrame(Beschreibung, Titel, wird ETA angezeigt etc.);
        new Thread(new Runnable()
            public void run()
            {
                doSomething(new ProgressListener() { /* gibt alles ans Progress Frame weiter */ };
            }
        }).start();
    }
    private void doSomething(ProgressListener l)
    {
         l.processStarted(0, 100);
         // jeder arbeitsschritt/durchlauf
         l.processStateChanged(...);
         l.processFinished();
    }
}

ACHTUNG: Hier warted der Starter-Thread nicht darauf, dass der andere Thread fertig wird. Wenn der Starter-Thread nämlich nicht selbst ein extra neu erstellter ist blockiert das den EDT und somit ermöglicht nur ein regelmäßiges Thread.yield() im Hintergrund eine Anzeige in der GUI was aber WorstPractice wäre.

Auf diese weise kannst du ohne deinen Hintergrund-Code zu verändern theoretisch auch eine Fortschirtts-Angabe übers Netzwerk oder auf die Kommandozeile schicken. Die Klasse ProgressFrame kann dann auch aufgrund der Geschwindigkeit mit der sich der Status erhöht bei linear ablaufenden Vorgängen ziemlich präzise eine ETA eigenständig ausgeben.

Den Quellcode für die Klassen und ein Vollständiges Beispiel für singelthread / multithread background anwendungen kann ich dir per PM schicken.
 
Zuletzt bearbeitet:

Thallius

Top Contributor
Danke,

ich habe es mit dem Worker gemacht aber das ganze Konstrukt finde ich total unsinnig. Da rufe ich im Worker eine Methode setProgress() auf die dann wiederum einen PropertyChange in meinem MainThread triggert. Wieviel komplizierter geht es denn noch?

Gruß

Claus
 

Tobse

Top Contributor
Du siehst: Ich habe es änlich umgesetzt. Es geht darum den Arbeits-Code vom GUI-Code so gut wie möglich fern zu halten. Und Listener sind eine wunderbare Art, genau das zu tun.

Und wenn das schon kompliziert ist: schau dir mal an wie die Listener für einen JButton oder eine JTable mit ihrem Eltern-Frame o.ä. zusammenabreiten. Da wirds dann richtig spaßig.
 

turtle

Top Contributor
Da rufe ich im Worker eine Methode setProgress() auf die dann wiederum einen PropertyChange in meinem MainThread triggert
Das liest sich kompliziert, aber alle GUI-Frameworks sind single-threaded. Also muss ein Background-Thread "irgendwie" dem GUI-Thread sagen, das es neu zeichnen soll. (Was wäre denn dein Alternativ-Vorschlag?)

Und da sind Listener eine gute Möglichkeit Background- und GUI-Thread, wie Tobse richtig anmerkte, zu entkoppeln.

Zum Thema SwingWorker habe ich übrigens mal einen Blog geschrieben den du hier findest.
 
Zuletzt bearbeitet:

Thallius

Top Contributor
Das liest sich kompliziert, aber alle GUI-Frameworks sind single-threaded. Also muss ein Background-Thread "irgendwie" dem GUI-Thread sagen, das es neu zeichnen soll. (Was wäre denn dein Alternativ-Vorschlag?)

Und da sind Listener eine gute Möglichkeit Background- und GUI-Thread, wie Tobse richtig anmerkte, zu entkoppeln.

Zum Thema SwingWorker habe ich übrigens mal einen Blog geschrieben den du hier findest.

Ich habe mich jetzt über den PropertyChangeListener genauer informiert. Jetzt verstehe ich das Ganze schon besser. Was ich s*****e finde ist, dass das alles im private Teil des Workers gekapselt ist, so dass man ja als Anfängern gar nicht verstehen kann was da eigentlich passiert. Entweder man nimmt das so hin (was einfach nicht mein Ding ist, ich will verstehen was ich programmiere) oder man muss sich das Ganze an zig anderen Stellen zusammen suchen, wie das ungefähr funktioniert. Zumal die gazen Tutorials einem da auch nicht helfen, weil es denen anscheinend auch egal ist warum es funktioniert. Hauptsache es geht.


Danke

Claus
 

turtle

Top Contributor
PropertyChangeListener genauer informiert. Jetzt verstehe ich das Ganze schon besser. Was ich s*****e finde ist, dass das alles im private Teil des Workers gekapselt ist,
Bahnhof???:L
Welcher PropertyChangeListener und insbesondere welcher Worker?

Vielleicht postest du mal etwas mehr Code?
 

Thallius

Top Contributor
So, sorry hatte die letzen Tage einfach zu viel zu tun um mich weiter darum zu kümmern.

So sieht es im Moment aus aber hier wartet der Mainthread natürlich nicht bis der Background Thread fertig ist.

Java:
	          public class getLicenseThread implements Runnable 
	 {
		  protected MainFrame frame;
		  public getLicenseThread(MainFrame frame) 
		  {
			  this.frame = frame;
		  }
		
		  @Override
		  public void run() 
		  {
		  }
	 }
	 
	 public void renewLicense(MainFrame frame, final String salt)
	 {
		 getLicenseThread pt=new getLicenseThread(frame) 
		 {
			 @Override
			 public void run() 
			 {

				final GetLicenseProgressPanel progressPanel=new GetLicenseProgressPanel();
    	                        ProgressWorker pw = new ProgressWorker(frame, progressPanel, salt);
	                pw.addPropertyChangeListener(new PropertyChangeListener() 
	                {
	                	@Override
	                    public void propertyChange(PropertyChangeEvent evt) 
	                    {
	                		String name = evt.getPropertyName();
	                		if (name.equals("progress")) 
	                		{
	                			int progress =  (Integer) evt.getNewValue(); // Hier den Wert angeben
	                			progressPanel.progressBar.setValue(progress);
	                			frame.repaint();
	                        }	
	                        else if (name.equals("state")) 
	                        {
	                        	SwingWorker.StateValue state = (SwingWorker.StateValue) evt.getNewValue();
	                            switch (state) 
	                            {
	                            	default:
	                             		break;
	                             	case DONE:
	                             		progressPanel.setVisible(false);
	                                    return;
	                            }
	                        }
	                    }
	                });
	                pw.execute();		
			 }
		 };
		 EventQueue.invokeLater(pt);
	 }
	 
	 public class ProgressWorker extends SwingWorker<Object, Object> 
	 {
		 private GetLicenseProgressPanel panel;
		 private MainFrame frame;
		 private String salt;
		 
		 public ProgressWorker(MainFrame frame,GetLicenseProgressPanel panel, String salt)
		 {
			 this.panel=panel;
			 this.frame=frame;
			 this.salt=salt;
		 }
		 
		 @Override
		 protected Object doInBackground() throws Exception 
		 {
                         // hier wird die eigentlich aktion ausgeführt
			 return null;
		 }
		 
		 public void updateProgress(int index)
		 {
			 setProgress(index);
		 }
	 }

Was muss ich nun in diesem Code machen, damit der Main Thread erst weiter läuft wenn Worker sagt Done?

Gruß

Claus
 
Zuletzt bearbeitet:
Ähnliche Java Themen
  Titel Forum Antworten Datum
R Java-Forum als Desktop-Background Allgemeine Java-Themen 4
T Background im Readmorebutton Allgemeine Java-Themen 6
Tausendsassa Interface Buttons Background ändern! Wie?? Allgemeine Java-Themen 10
E programm im background tastendruck abfangen Allgemeine Java-Themen 4
J Flash GUI JAVA Background Allgemeine Java-Themen 12
S Image als Background Allgemeine Java-Themen 5
Tarrew Threading - Unregelmäßige Lock-Vergabe Allgemeine Java-Themen 0
C Threading mit BufferedReader/InputStream & sockets Allgemeine Java-Themen 0
B Threading Allgemeine Java-Themen 23
Luk10 Multi-Threading mit join() Allgemeine Java-Themen 16
R Threading und Rekursion führen zu “GC overhead limit exceeded” Allgemeine Java-Themen 4
SuperSeppel13 Bilder auf Anfrage laden - Threading Allgemeine Java-Themen 3
J Threading / Callables Allgemeine Java-Themen 8
K Threading - schreiben auf Hashmap/löschen - ConcurrentModificationException Allgemeine Java-Themen 3
F Threading oder kein Threading - das ist hier die Frage. Allgemeine Java-Themen 23
G Fehlerbereinigung bei Multi Threading Anwedung Allgemeine Java-Themen 2
OnDemand Java Deployment Vaadin Allgemeine Java-Themen 3
D Hat Java eine Library um JavaScript auszuwerten? Allgemeine Java-Themen 2
Zrebna Wieso sind eigentlich JUnit-Tests in src/test/java platziert - nur Konvention? Allgemeine Java-Themen 7
N LlaMA, KI, java-llama.cpp Allgemeine Java-Themen 39
V Java-Codierungsherausforderung: Navigieren durch die Macken der Datumsmanipulation Allgemeine Java-Themen 2
E Output Fehler (Java-Programm Kuchen) Allgemeine Java-Themen 11
M java: unexpected type Allgemeine Java-Themen 2
harrytut Java Input/Output Tests Junit Allgemeine Java-Themen 3
B Java Discord bot auf ein Root Server? Allgemeine Java-Themen 1
BetziTheRealOne Java PKIX path building failed as non Admin Allgemeine Java-Themen 15
D Linux, Java-Version wird nicht erkannt bzw. welche Einstellung fehlt noch? Allgemeine Java-Themen 19
KonradN Java 21 Release Allgemeine Java-Themen 5
V Umgang mit fehlenden Daten in einer Java-Datenanalyseanwendung Allgemeine Java-Themen 5
P Fehler: Hauptklasse Main konnte nicht gefunden oder geladen werden Ursache: java.lang.ClassNotFoundException: Main Allgemeine Java-Themen 24
K Java Anwendung machen Anleitung Allgemeine Java-Themen 5
G java.io.listFiles() Allgemeine Java-Themen 3
8u3631984 Frage zu Java Streams min / max Allgemeine Java-Themen 17
S Java Programm lässt sich vom USB-Stick starten, aber nicht von HDD Allgemeine Java-Themen 16
K Java-Projekt Allgemeine Java-Themen 11
K Java-Projekt Allgemeine Java-Themen 0
ruutaiokwu Welcher Browser unterstützt heutzutage noch Java Applets? Allgemeine Java-Themen 5
Jose05 Java-Klasse im extra cmd-Fenster ausführen Allgemeine Java-Themen 3
rode45e Java Threads Allgemeine Java-Themen 4
G java.io.listFiles() Allgemeine Java-Themen 2
N Java Dynamic Proxy Allgemeine Java-Themen 3
N Leichte Java Gegner Ki Allgemeine Java-Themen 10
A Java modul Problem Allgemeine Java-Themen 4
Thomasneuling Java Jar datei erstellen, von Projekt, dass auch Javafx Dateien, FXML Dateien und CSS Dateien, sowie Bilder enthält? Allgemeine Java-Themen 14
V Funktionale Schnittstelle in Java Allgemeine Java-Themen 3
OnDemand Java String in Hashmap als Key NULL Allgemeine Java-Themen 27
urmelausdemeis Exception in thread "main" java.lang.Error: Unresolved compilation problem: Allgemeine Java-Themen 7
berserkerdq2 Wenn ich bei Intelij javafx mit maven importieren will, muss ich das in die pom.xml reintun, aber warum noch in module-info.java? Allgemeine Java-Themen 3
KonradN Java 20 am 21. März Allgemeine Java-Themen 1
O Java Website Stock Bot Allgemeine Java-Themen 3
J Front-/Backend in Java Allgemeine Java-Themen 14
doopexxx JAVA Google Webcrawler Allgemeine Java-Themen 1
J JavaScript innerhalb eines Java Projekts ausführen Allgemeine Java-Themen 2
A Java Programm erstellen hilfe Allgemeine Java-Themen 10
G java.lang.NoClassDefFoundError: org/aspectj/lang/Signature Allgemeine Java-Themen 2
lalex1491 Java Aktienkurse nachfragen Allgemeine Java-Themen 4
J Class to link Java Allgemeine Java-Themen 4
V Wie funktioniert das Schlüsselwort "final" von Java? Allgemeine Java-Themen 19
mrStudent Inferenz JAVA Allgemeine Java-Themen 6
U URI Rechner (Java Script) Allgemeine Java-Themen 7
TheSkyRider Java Geburtsdatum Textfeld Allgemeine Java-Themen 7
mihe7 Java 19 JavaDocs: Browserintegration Allgemeine Java-Themen 0
Encera Gleichzeitiges Ausführen und verbinden von 2 Java-Klassen über die Eingabeaufforderung und Eclipse Allgemeine Java-Themen 21
H Java Rechner Programmierung der Mathematik Allgemeine Java-Themen 33
Lennox Schinkel Java Kara Auf einen Java Host laufen lassen Allgemeine Java-Themen 17
C Fußnoten von DocX mit Java Allgemeine Java-Themen 2
C Fußnoten in DocX mit Java Allgemeine Java-Themen 1
M Aussagenlogik in Java Programmieren Allgemeine Java-Themen 22
B Per Java Word Dokument schreiben? Allgemeine Java-Themen 8
krgewb Java-Bibliothek für ONVIF Allgemeine Java-Themen 1
KonradN Oracle übergibt (Java Teile der) GraalVM Community Edition an OpenJDK Community Allgemeine Java-Themen 2
Momo16 Brauche Hilfe - Java Projekt kann nicht erstellt werden Allgemeine Java-Themen 12
B Java mit command line und jars benutzen? Allgemeine Java-Themen 18
M Java Überprüfen ob .exe-Datei bereits ausgeführt wird Allgemeine Java-Themen 2
B HTTP Allgemeine Fragen über Suchmaschine nutzen mit Java Allgemeine Java-Themen 20
Mick P. F. Wie kriege ich die Fehlermeldung "java: symbol lookup error: ..." weg? Allgemeine Java-Themen 11
K Nachhilfe Java Allgemeine Java-Themen 11
KonradN Java 19 Allgemeine Java-Themen 11
F IDEA IntelliJ Java Songliste erstellen Allgemeine Java-Themen 6
TheSepp Java bestimmtes Array auf den Wert 0 setzen Allgemeine Java-Themen 32
B Java Reflection Probleme beim wehcselseitigen Referenzieren zweier Klassen/Objekte Allgemeine Java-Themen 14
Sachinbhatt Sind alle Methoden in Java implizit virtuell Allgemeine Java-Themen 2
E Java und integrierte Grafikkarten Allgemeine Java-Themen 18
Sachinbhatt Wie wird die Typumwandlung bei Mehrfachvererbung in Java implementiert? Allgemeine Java-Themen 3
Peterw73 Hilfe bei Java gesucht Allgemeine Java-Themen 3
A Java unter Win 10 Allgemeine Java-Themen 1
B Woher kommen die Bildschirmkoordinaten beim java Robot? Allgemeine Java-Themen 14
P9cman java.Lang Klassen fehlen in JRE System Library Allgemeine Java-Themen 1
T Java Robot Class - Bot Allgemeine Java-Themen 3
E Wie Java Heap Space vergrößern? Allgemeine Java-Themen 3
B Java Programm auf virutellem Desktop laufen lassen? Allgemeine Java-Themen 1
D VBA Code mit Java ausführen möglich? Allgemeine Java-Themen 10
berserkerdq2 Threads, wie genau läuft das in Java ab? (Ich kann Threads erstellen und nutzen, nur das Verständnis) Allgemeine Java-Themen 6
izoards Java Home Pfad unabhängig von der Version Allgemeine Java-Themen 7
N JAVA-Code mit Grafikfenster zeichnet in Windows, aber nicht Mac. Allgemeine Java-Themen 4
L Java überprüfen lassen, ob sich ein gegebener Pfad / das Programm an sich auf einer CD oder Festplatte befindet Allgemeine Java-Themen 14
KonradN CVE-2022-21449: Fehler in Java bei Signaturprüfung Allgemeine Java-Themen 20
berserkerdq2 Java sql Allgemeine Java-Themen 15
JordenJost Unverständlicher Java code? Allgemeine Java-Themen 21
LimDul XSD To Java - Überschreiben von Assoziationen Allgemeine Java-Themen 1

Ähnliche Java Themen

Neue Themen


Oben