Swing Java Swing Gui und nebenläufige Threads

rikischiki

Mitglied
Hallo zusammen. Ich bin bei der Programmierung eines kleinen Programmes auf ein Problem gestossen für das ich bisher noch keine Lösung gefunden habe. Es sei vorgewarnt das ich nicht allzuviel Erfahrung mit Java habe. Der Programmaufbau sieht folgendermassen aus:

[Gui] <----> [Controller/Datenfluss Klasse] <----> [Arbeiter/Berechnungsklassen]

Die Gui kommuniziert also über [Controller/Datenfluss Klasse] an die Arbeiterklassen weiter was berechnet werden soll. Die Gui/Swing komponente wird über folgenden Code in einem eigenen Thread gestartet:

[Java]
private static ProgramWindow mainProgramFrame;

javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
mainProgramFrame = new ProgramWindow(initialize);
mainProgramFrame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
[/Java]

Wenn nun über die Gui eine neue Berechnung eingeleitet wird, wird in den Arbeiterklassen wiederum ein eigener Thread erstellt, der die entsprechende Berechnung abarbeitet. Diese Arbeiter-Threads erstelle ich folgendermaßen:

[Java]
Thread createOrganismThread = new Thread(new CreateInitialOrganisms(this, organismDimension, organismCount));
createOrganismThread.start();
[/Java]

und die eigendliche Thread Klasse:

[Java]
public class CreateInitialOrganisms implements Runnable {

[...]

public void run() {

[Berechnung]

}

}
[/Java]

Das Problem das hierbei entsteht ist, dass die Gui zwar nicht blockiert, allerdings unfassbar langsam läuft und quasi nichtmehr zu gebrauchen ist. Ich hab es schon mit der Heruntersetzung der entsprechenden Priorität des Arbeiter-Threads probiert, aber immer mit dem selben Ergebniss - namentlich, die Gui ist nichtmehr sinnvoll benutzbar. Irgendwo wird hier denke ich etwas falsch gemacht, aber ich weis nicht wirklich wo. Der Arbeiter-Thread an sich greift auf keine Ressourcen von ausserhalb zu sondern sendet, wenn beendet seine Berechnungen zurück.
 
Zuletzt bearbeitet:
Hallo,

rikischiki hat gesagt.:
allerdings unfassbar langsam läuft und quasi nichtmehr zu gebrauchen ist
Wie äußert sich dieses, bzw. was ist langsam?

rikischiki hat gesagt.:
sendet, wenn beendet seine Berechnungen zurück.
Wohin wird das Ergebnis gesendet.

Was für eine Berechnung ist es? Wie lange dauert diese? Wartet irgendetwas auf das Ergebnis? Wie wird auf das Ergebnis gewartet? Werden evtl. ungewollt zu viele Threats erzeugt?

MfG
hansmueller
 
Ich habe hier mal ein kleines Beispiel zusammengestückelt das ihr euch schnell kompillieren könnt. Führt es aus und zieht das entstehende Fenster ein bisschen auf eurem Desktop rum. Es besteht aus folgenden zwei Klassen:

[Java]
import javax.swing.JButton;
import javax.swing.JFrame;

public class Init {

public Init () {

}

/**
* @param args
*/
public static void main(String[] args) {

Init init = new Init();

javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
JFrame frame = new JFrame("Test Threading");
JButton button = new JButton("Start");
frame.add(button);
frame.pack();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});

Thread workerThread = new Thread(new WorkerThread(init));
workerThread.start();
}

}
[/Java]


[Java]
import java.util.ArrayList;
import javax.swing.JFrame;


public class WorkerThread implements Runnable {

private ArrayList<JFrame> list;


public WorkerThread(Init init) {
list = new ArrayList<JFrame>();
}

@Override
public void run() {
for (int i = 0; i < 10000000; i++)
list.add(new JFrame());
}

}
[/Java]

Das Programm ist also wirklich nur eine minimale Gui und ein Thread, der JFrames erzeugt und auf eine ArrayList addet. (zweiteres um eine aufwändige Berechnung mit Speicherzugriff zu simulieren)

[EDIT] Ok, das Problem liegt an der .add() Methode der ArrayList. Sie verursacht anscheinend, dass auch die gesamte Gui blockiert wenn sie schnell hintereinander aufgerufen wird.
 
Zuletzt bearbeitet:
Auf die Idee, dass am Erstellen einen JFrames liegen könnte, könnte man auch kommen 😉
Schau' dir mal an, was beim erstellen eines JFrames intern so alles passiert. Wenn du aufgibst (nicht wenn du damit "fertig" bist, sondern wenn du aufgibst!) könntest du das z.B. durch einen Array ersetzen, oder eine ArrayList mit ArrayLists.

Ob es tatsächlich DIE Ursache ist, kann man kaum sagen, aber mit nicht-GUI-Objekten wäre das zumindest... "repräsentativer"...

EDIT: Eher im Gegenteil. Bei mir stottert er bei ArrayLists eher rum als bei JFrames...

EDIT2: An der add-Methode selbt kann es aber nicht liegen. Vermutlich eher an den Objektallokationen: Wenn man immer wieder dasSELBE Objekt in die Liste legt, ist er ruck-zuck fertig und scheint auch nicht zu blockieren. Müßte man aber noch ausführlicher testen.
 
Zuletzt bearbeitet:
Hi,

meine Erfahrung unter Java SE: Graphik mit Threads ist langsam.

Allerdings habe ich in meinem Java-Audio-Player für Java SE wie folgt
GUI verbaut (applet, alles JKlassen).

1. Hautpklasse für Sound
2. Hauptklasse für GUI
GUI-Elemente des Fensters sind je eigene Klassen und bei
Animation wie scrollen mit je eigenen Threads.
Synchronisierung der GUI-Elemente per Thread der Hauptklase.
3. Applet, dass beide obigen Hauptklassen aktiviert.
Sound und GUI werden per Thread synchronisert.

Das Malen per paint() etc. ist in einem Thread hinterlegt, der
die Player-GUI refresht. Und da ist der Knackpunkt.

Events sind z.T. in GUI-Elemente-übergreifende Klassen hinterlegt,
die perdiodisch abgefragt werden müssen, da diese u.a.
die Sounds der Ecents der Buttons oder des Fensters
steuern.

Mit anderen Worten: Threads ohne Ende, die teilweise dynamisch
erzeugt, benutzt und geschlossen werden, so dass Java
aufräumt ohne Ende.
Ich arbeite mit vielen globalen Variablen, um Aufräumarbeiten
zu sparen.
Aufgrund der Vernetzung werden oft static Grössen verwendet.
Die komplette Kapselung, wie sie exakt OOP-treu wäre,
halte ich für unmöglich, wenn Graphic überhaupt
laufen soll.

Mein Player ist unter audio, flash and java zu finden. Die GUI-Problemen
werden in der GUI-Konfigurationsdatei erklärt, da dementsprechend
Einstellungen zur GUI-Steuerung zu treffen sind, z.B. Refreshrate
des Malen ...
Wenn sich jemand aus Neugierde das antun will, dann viel Vergnügen
beim Probieren 🙂

Noch etwas: Wer wirklich nicht durchhalten will, sollte Echtzeitprogrammierung
unter Java SE mit J-Klassen in Windows nicht angehen, sondern
Spezialversionen von Java benutzten, da diese - falls gepflegt werden -
einfacherer sein könnten, aber dann betriebsystemspezifisch.
Und letzteres kam für mich nicht in Frage, da nur Java SE
ziemlich verbreitet ist.

P.S: Alternative ist Flash und wer das nicht mag: Microsoft Net Framework
mit z.B. Silverlight. Flash habe ich auch ausprobiert.
Bei Microsoft bin ich etliche Male wegen Kompatibilitätsprobleme
auf die Schnauze gefallen: Microsoft schaltet gerne ab und man
hat dann für umsonst programmiert. Im Bereich Video nutze ich
Flash, Quicktime und HTML-5-Media (auch für Audio) kombiniert
mit Javascript. Mein Javaplayer für Audio ist einfach zu
ressourcenhungrig. Ergo: Java ist leider aussen vor und
Microsoft stellt sich bei mir hinten an, da ich Opera-Browser
empfehle, der auch von Anfang an HTML-5-Media kontinuierlich
kompatibel integriert hat (was Microsoft erst ab IE 9 mit
Google-Plugin-Krücke schafft). Wer die Kombination von
Audio und Video sehen will: Arbeitspapier: Analyse SGB II Grundsicherung für Arbeitsuchende (Hartz 4) aber Achtung,
diese Seite ist komplett eigenwillig programmiert. Wer
den Internet Explorer nutzt, sollte dann die HTML-Version
der Webseite angehen (die IE-Version ist z.T. anders angelegt
und prgrammiert und zwar speziell für den Internet Explorer 6
bis IE 8 - klar komplett ohne HTML-Media, dafür NUR mit etwas Flash
und - logisch - mit dem guten alten BGSOUND, also mp3).
Wer Firefox oder Seamonkey verwendet - diese Browser könnten arg
langsam sein. Safari und Google wurde nicht getestet.
Die Webseite benötigt aktive Soundboxen oder Kopfhörer.
 

Zurück
Oben