# Auf Ende von mehreren Threads warten, ohne den EDT zu blockieren



## tomse (31. Mai 2009)

Hallo alle zusammen,

ich hoffe jemand kann mir bei folgendem Problem helfen:

mein Programm lädt mehrere Dateien parallel in verschiedenen Threads.
Damit der User weiss was los ist, wird der Progress in einem modalen Dialog dargestellt. 
Programmtechnisch sieht das vereinfacht folgendermassen aus:

Pro zu ladender Datei wird ein Thread-Objekt angelegt und einer ProgressManager Klasse uebergeben. Diese besitzt eine 'start' Methode, welche die ersten 3 Threads started und den Dialog auf 'visible' setzt. Sobald ein Thread beendet ist, wird der nächste gestartet, bis alle Threads ausgeführt wurden. Nun wird der Dialog wieder auf 'invisible' gesetzt und der Kontrollfluss der 'start' Methode kehrt zurueck. 
Die einzelnen Threads kennen den Dialog und melden ihren Progress, der über 'SwingUtilities.invokeLater' wieder in den EDT umgeleitet wird. Die einzelnen geladenen Dateien werden in den Thread-Objekten abgelegt und nach Ablauf der 'start' Methode aus diesen rausgeholt.

Nun das eigentliche Problem:
Den Dialog will ich durch eine Ausgabe auf das GlassPane ersetzen. Das Problem ist jetzt, dass die 'start' Methode sofort zurueckkehrt (da alles andere ja in den separaten Threads erledigt wird) und damit schon versucht wird auf das Ergebnis der einzelnen Threads zuzugreifen, bevor diese fertig (oder ueberhaupt gestartet) sind. Vorher hat der modale Dialog das verhindert. Um das Problem zu lösen hab ich ans Ende der 'start' Methode ein 'CountDownLatch.await' gesetzt, was von den einzelnen Threads runtergezählt wird. Das funkioniert leider nicht, da dadurch der EDT blockiert wird und die invokeLater Aufrufe die GUI nicht mehr aktualisieren können.

Was ich also bräuchte, wäre ein Mechanismus wie mit dem Modalen Dialog. Also wie kann der modale Dialog verhindern, dass der Kontrollfluss der 'start'-Methode zurückkehrt ohne den EDT zu Blockieren?

Anmerkung:
Ich koennte natürlich über einen Callback auf das Ende der Threads warten, und dann weitermachen, möchte aber meine ürsprüngliche Implementierung nicht umstrukturieren.


----------



## Marco13 (31. Mai 2009)

tomse hat gesagt.:


> Was ich also bräuchte, wäre ein Mechanismus wie mit dem Modalen Dialog. Also wie kann der modale Dialog verhindern, dass der Kontrollfluss der 'start'-Methode zurückkehrt ohne den EDT zu Blockieren?



Die Antwort steht in der Klasse "dialog", in der "show"-Methode: Wenn der Dialog NICHT modal ist, wird er einfach angezeigt. Aber WENN er modal ist, passieren viele, viele, ziemlich dramatische Sachen (es wird sozusagen ein neuer EDT erstellt, der dem ursprünglichen EDT übergeordnet ist!) die man kaum selbst nachbauen kann.

Ein Ansatz wäre vielleicht - wenn ich das richtig verstanden habe - die "start"-Methode von einem eigenen Thread ausführen zu lassen?! DEN kann man dann ja blockieren, solange man will....


----------

