Darf Swing-Klassen in Nicht-EDT-Threads geladen werden?

8

Nach Einführung des Java-Speichermodells wurden die Swing-Richtlinien dahingehend geändert, dass alle Swing-Komponenten auf dem EDT instanziiert werden müssen, um einen nicht veröffentlichten Instanzstatus zu vermeiden.

Was ich nirgendwo finden konnte, ist, ob das Classloading auch im EDT enthalten sein soll oder können wir wichtige Swing-Klassen in einem Hintergrundthread vorladen? Gibt es dazu eine offizielle Stellungnahme von Sun / Oracle? Gibt es Klassen, von denen bekannt ist, dass sie einen nicht-threadsicheren statischen Zustand besitzen und daher auf EDT geladen werden müssen?

Klarstellung, um Nemis Frage zu beantworten: Dies ist ein praktisches Problem. Ein beträchtlicher Teil der Startzeit unserer Anwendung ist das Laden von Klassen und das Laden von Schriften / Bildern auf dem EDT. Das meiste davon kann Swing und verwandten Bibliotheken zugeschrieben werden.

Hier ist der Hintergrund: Wie viele andere Swing-Apps werden beim Start viele Formulare vorkonfiguriert, um die Benutzeroberfläche reaktionsfähiger zu machen. Nach dem Profiling stellten wir fest, dass die tatsächliche Zeit für die Formularkonstruktion relativ schnell ist - das Laden aller Klassen und Schriftarten verlangsamt sich (Festplattenlesevorgänge sind langsam im Firmen-Setup mit On-Access-Virenscanner, Überwachungsscanner, Überwachungs-Tracker und Gott weiß, was noch auf dem HDD-Treiber angeheftet wurde).

Wir haben versucht, die gleichen Formen in einem Hintergrund-Thread zu konstruieren (gegen die Regeln von Swing) und sie dann wegzuwerfen. Sobald wir fertig sind, konstruieren wir dieselben Formulare auf dem EDT, was viel schneller ist, wenn alle Klassen geladen sind und alle anderen Dateien im Plattencache sind. Es funktioniert für uns, und wir werden wahrscheinlich weitermachen, wenn nicht wirklich etwas Schlimmes passiert.

Was ich frage ist, ob dies eine sichere Übung, eine gute Übung oder ein Hack ist?

    
ddimitrov 07.06.2010, 01:26
quelle

3 Antworten

2

Die Beweise scheinen darauf hinzuweisen, dass es sicher ist - aber andererseits, wie ddimitrov in den Kommentaren sagt - die Chancen stehen gut, keine subtilen Thread-Bugs aufgrund von nicht veröffentlichten Änderungen zu finden, weil typische Maschinen nur wenige Kerne haben L2 / L3-Caches werden gemeinsam genutzt. (L1-Caches sind pro Kern, aber in der Regel sehr klein.)

Wenn Sie sicherstellen möchten, dass aufgrund der Hintergrund-Klassenladung kein Problem auftritt, dann ist es wahrscheinlich am sichersten, die Klassen auf der ETD beizubehalten. Um eine Live-Benutzeroberfläche zu verwalten, erstellen Sie einen benutzerdefinierten Klassenlader, der auch Ereignisse zwischen den einzelnen Klassen pumpt. (Abhängigkeiten werden direkt geladen, so dass die Verzögerung nur für die Dauer des Ladens nur einer Klasse gilt.) Angenommen, dieser Klassenlader ist mit Ihrer Anwendung gepackt, dann kann er einfach alle Klassenladevorgänge auf seinen Klassenlader verschieben.

Alternativ können sekundäre Ereigniswarteschlangen verwendet werden, die auf separaten Threads ausgeführt werden (z. B. modale Dialoge und die Spin -Bibliothek). . Das bedeutet, Swing kann auf jedem Thread laufen, solange es nur auf einem läuft, und bedeutet, dass es update-konsistent sein muss (oder dass wir alle bisher nur sehr viel Glück hatten!). Auf dieser Grundlage könnten Sie Laden Sie Ihre Klassen auf den primären EDT und starten Sie einen sekundären EDT, um die UI-Ereignisse zu pumpen, und halten Sie die Benutzeroberfläche so ansprechend - so wie ein modaler Dialog funktioniert. Das Spin-Dienstprogramm pumpt EDT-Ereignisse für Sie oder Sie können einen neuen EDT von Hand erstellen.

mdma 09.06.2010, 18:58
quelle
2

Es ist sicher. Siehe: Ссылка (die Regel für einzelne Threads)

Wenn Sie Angst haben oder Feedback / Debuggen möchten, schauen Sie sich dieses FEST / Swing-Tool an: Ссылка (" Testen des Zugriffs auf GUI-Komponenten im EDT ") - es ist eine benutzerdefinierte RepaintManager , die fehlschlägt, wenn Sie gegen die EDT-Zugriffsrichtlinie verstoßen.

Sie können dies auch hilfreich finden: Ссылка

Sie erwähnen das Laden von Klassen nicht explizit, aber sie erklären, um was es bei der EDT-Zugriffsrichtlinie geht.

    
Konrad Garus 09.06.2010 17:04
quelle
0

Obwohl Sie technisch korrekt sind - ich habe noch nie von einem Problem mit dem Rendern der Formulare in einem anderen Thread gehört, solange Sie nichts mit ihnen machen, sobald sie realisiert sind, außer mit dem EDT (nach dem Original der Sonne) Richtlinien).

Früher waren die Richtlinien der Sonne, aber Sun änderte sie so, wie Sie es vorgaben - also bin ich mir sicher, dass jemand einen möglichen Konflikt gefunden oder geschaffen hat, aber ich bin mir auch sicher, dass es immer noch schwer werden wird arbeiten und fast keiner folgt diesen Richtlinien.

Was Ihre Frage anbelangt, bin ich sicher, dass Sie die Klassen laden können, solange Sie keine Objekte instanziieren und trotzdem innerhalb der strengsten Richtlinien bleiben.

Der EDT wird nur verwendet, um Thread-Kollisionen zu vermeiden, da Swing single-threaded ist (per Design). Wenn Sie nur die Klassen laden und keine Instanzen instanziieren, öffnen Sie sich nicht für Threading-Probleme.

    
Bill K 07.06.2010 23:20
quelle

Tags und Links