35 Stimmen

Ist es sicher, Swing/AWT-Widgets NICHT auf dem Event Dispatch Thread zu konstruieren?

Ich habe das Programm in die Substanz in meine Anwendung zu integrieren und stieß dabei auf mehrere Probleme mit den internen EDT (Event Dispatch Thread) Prüfroutinen. Substance weigert sich absolut, UI-Klassen außerhalb des EDT zu konstruieren. Ich habe viel mit Swing/AWT gearbeitet und kenne die meisten Regeln bezüglich des EDT. Ich verwende SwingWorker, SwingUtilties.invokeLater, um Komponenten zu ändern. Ich dachte immer, Komponenten könnten KONSTRUKTURIERT außerhalb des EDT, muss aber realisiert y manipuliert auf der EDT. Mit anderen Worten: Sie können die Standardeinstellungen im Hintergrund erstellen und einrichten, aber der Aufruf von pack/setVisible muss im EDT erfolgen, ebenso wie alle nachfolgenden Aufrufe zur Bearbeitung der Komponente.

Der Grund, warum ich frage, ist, dass ich ein besonders "beefy" Fenster zu konstruieren, mit vielen Widgets, Zustand und Ressourcen (viele Symbole) haben. Bisher habe ich das Fenster in der Background-Methode eines SwingWorkers konstruiert und das Fenster in der Done-Methode sichtbar gemacht. Ich hatte nie ein einziges Problem. Beim Wechsel zu Substance beißt mich die interne EDT-Überprüfung.

Ich konnte den Code umgestalten, um dies zu umgehen. Ich kann auf dem EDT konstruieren, was keine gute Lösung ist, da die gesamte Anwendung blockiert wird. Ich kann auch refactor noch mehr und versuchen mein Bestes, um alle zusätzlichen Ressourcen außerhalb der EDT zu laden.

Zum Abschluss ... Ist es sicher zu konstruieren Swing/AWT-Widgets NICHT auf dem Event Dispatch Thread?

41voto

Rahel Lüthy Punkte 6307

Sun hat die Regeln im Jahr 2004 geändert. Zuvor durften Sie die Komponenten außerhalb des EDT erstellen und mussten erst dann in den EDT wechseln, wenn die Komponente erstellt worden war. realisiert .

Die neue Vorschrift lautet jetzt:

Um die Möglichkeit einer Blockade zu vermeiden, müssen Sie äußerst sorgfältig darauf achten, dass Swing Komponenten und Modelle erstellt , geändert und nur von der ereignisauslösenden Thread abgefragt.

diese Blogbeitrag von mir enthält weitere Details, einschließlich Links zu anderen verwandten Artikeln. Beachten Sie, dass alle offiziellen Sun Beispiele wurden umgeschrieben und sind in dieser Hinsicht sehr streng.

Historisch gesehen war es wahrscheinlich die zunehmende Verfügbarkeit von Multicore-Computern als Desktop-Maschinen, die die Neuformulierung der Regel motiviert hat - Threading-Probleme wurden auf dem Client-Stack immer offensichtlicher, und durch sehr strenge EDT-Richtlinien können viele von ihnen von vornherein verhindert werden.

1 Stimmen

Hinterhältig hinterhältig ... danke für den konkreten Beweis, nach dem ich mich gesehnt habe. Zeit zum Refactoring!

0 Stimmen

Es sind eher Race Conditions als Deadlocks, die das Problem verursachen.

0 Stimmen

@tom: Ich stimme zu, was die Race Conditions angeht - ich habe nie behauptet, dass es sich um Deadlocks handelt (ich habe nur auf "Threading-Probleme" verwiesen).

9voto

Esko Punkte 28242

Nein.

Der einfache Grund dafür ist, dass sogar der EDT in einigen seltenen Fällen zum Deadlock neigt, und dass es im Allgemeinen einfach ist, die Benutzeroberfläche zu blockieren, wenn man Swing ( Das wurde mir jedenfalls gesagt. ). Ich empfehle Ihnen, diese drei Artikel aus Kirills (dem Substance-Entwickler) Blog zu lesen:

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X