Ich habe vor einiger Zeit einen wirklich guten Blog gelesen, der dieses Thema behandelt (von Karl Bielefeldt erwähnt). Grundsätzlich heißt es, dass es sehr gefährlich ist, den Thread des UI-Kits sicher zu machen, da er mögliche Deadlocks einführt und davon abhängt, wie es ist umgesetzt, Rennbedingungen in den Rahmen.
Es gibt auch eine Leistungsüberlegung. Nicht so sehr jetzt, aber als Swing zum ersten Mal veröffentlicht wurde, wurde es heftig für seine Leistung kritisiert (war schlecht), aber das war nicht wirklich Swings Schuld, es war das mangelnde Wissen der Leute darüber, wie man es benutzt.
SWT erzwingt das Konzept der Threadsicherheit, indem es Ausnahmen auslöst, wenn Sie nicht hübsch dagegen verstoßen, aber zumindest darauf aufmerksam gemacht werden.
Wenn Sie sich zum Beispiel den Malprozess ansehen, ist die Reihenfolge, in der die Elemente gemalt werden, sehr wichtig. Sie möchten nicht, dass das Malen einer Komponente einen Nebeneffekt auf einen anderen Teil des Bildschirms hat. Stellen Sie sich vor, Sie könnten die Texteigenschaft einer Beschriftung aktualisieren, aber sie wurde von zwei verschiedenen Threads gezeichnet. Dies könnte zu einer beschädigten Ausgabe führen. Alle Malvorgänge werden also in einem einzigen Thread ausgeführt, normalerweise basierend auf der Reihenfolge der Anforderungen / Anforderungen (aber manchmal verdichtet, um die Anzahl der tatsächlichen physischen Malzyklen zu reduzieren).
Sie erwähnen den Wechsel von Swing zu JavaFX, aber Sie hätten dieses Problem mit so gut wie jedem UI-Framework (nicht nur mit Thick Clients, sondern auch mit Web). Swing scheint das Problem hervorzuheben.
Sie könnten eine Zwischenschicht (einen Controller eines Controllers?) Entwerfen, deren Aufgabe es ist, sicherzustellen, dass Aufrufe an die Benutzeroberfläche korrekt synchronisiert werden. Es ist unmöglich, genau zu wissen, wie Sie Ihre Nicht-UI-Teile Ihrer API aus der Perspektive der UI-API entwerfen könnten, und die meisten Entwickler würden sich darüber beschweren, dass ein in die UI-API implementierter Thread-Schutz zu restriktiv war oder nicht ihren Anforderungen entsprach. Besser, Sie können entscheiden, wie Sie dieses Problem lösen möchten, basierend auf Ihren Anforderungen
Eines der größten Probleme, das Sie berücksichtigen müssen, ist die Möglichkeit, eine bestimmte Reihenfolge von Ereignissen auf der Grundlage bekannter Eingaben zu rechtfertigen. Wenn der Benutzer beispielsweise die Größe des Fensters ändert und das Ereigniswarteschlangenmodell garantiert, dass eine bestimmte Reihenfolge von Ereignissen auftritt, scheint dies einfach zu sein. Wenn die Warteschlange jedoch zulässt, dass Ereignisse von anderen Threads ausgelöst werden, kann die Reihenfolge in nicht mehr garantiert werden Wenn die Ereignisse eintreten könnten (eine Racebedingung), muss man sich plötzlich Sorgen über verschiedene Zustände machen und nichts tun, bis etwas anderes passiert und man beginnt, Zustandsflaggen zu teilen, und am Ende bekommt man Spaghetti.
Okay, Sie könnten das lösen, indem Sie eine Art Warteschlange haben, die die Ereignisse nach dem Zeitpunkt ihrer Ausgabe anordnet. Aber haben wir das nicht schon? Außerdem können Sie immer noch nicht garantieren, dass Thread B seine Ereignisse NACH Thread A generiert
Der Hauptgrund, warum Menschen sich darüber aufregen, über ihren Code nachdenken zu müssen, ist, dass sie gezwungen sind, über ihren Code / ihr Design nachzudenken. "Warum kann es nicht einfacher sein?" Einfacher geht es nicht, denn es ist kein einfaches Problem.
Ich erinnere mich, als die PS3 herausgebracht wurde und Sony den Cell-Prozessor auf den neuesten Stand brachte. Er ist in der Lage, verschiedene Logikzeilen auszuführen, Audio- und Videodaten zu dekodieren, Modelldaten zu laden und aufzulösen. Ein Spieleentwickler fragte: "Das ist alles großartig, aber wie synchronisiert man die Streams?"
Das Problem, von dem der Entwickler sprach, war, dass all diese separaten Streams zu einem bestimmten Zeitpunkt für die Ausgabe auf eine einzelne Pipe synchronisiert werden mussten. Der arme Moderator zuckte nur mit den Achseln, da es kein Thema war, mit dem sie vertraut waren. Offensichtlich hatten sie Lösungen, um dieses Problem zu lösen, aber es war zu der Zeit lustig.
Moderne Computer nehmen eine Menge Eingaben von vielen verschiedenen Orten gleichzeitig auf. Alle Eingaben müssen verarbeitet und an den Benutzer weitergeleitet werden, ohne dass die Darstellung anderer Informationen beeinträchtigt wird. Es handelt sich also um ein komplexes Problem eine einfache Lösung.
Da Sie nun die Möglichkeit haben, Frameworks zu wechseln, ist dies nicht einfach zu entwerfen, ABER nehmen Sie sich einen Moment Zeit für MVC. MVC kann mehrschichtig sein, dh Sie könnten eine MVC haben, die sich direkt mit der Verwaltung des UI-Frameworks befasst könnte dies dann wieder in eine übergeordnete MVC-Ebene einschließen, die sich mit Interaktionen mit anderen (möglicherweise multi-threading) Frameworks befasst. Es wäre die Verantwortung dieser Ebene, zu bestimmen, wie die untergeordnete MVC-Ebene benachrichtigt / aktualisiert wird.
Anschließend verwenden Sie die Codierung, um Entwurfsmuster und Factory- oder Builder-Muster für die Erstellung dieser verschiedenen Ebenen zu verknüpfen. Dies bedeutet, dass Sie Multithread-Frameworks durch die Verwendung einer mittleren Ebene als Idee von der UI-Ebene entkoppelt werden.