Jakiś czas temu przeczytałem naprawdę dobrego bloga, który omawia ten problem (wspomniany przez Karla Bielefeldta), co w zasadzie mówi, że bardzo niebezpieczne jest, aby uczynić zestaw interfejsu użytkownika wątkiem bezpiecznym, ponieważ wprowadza on potencjalne impasy i zależy od tego, jak to jest zaimplementowano warunki wyścigu do ram.
Istnieje również kwestia wydajności. Nie tak bardzo teraz, ale kiedy Swing został wydany po raz pierwszy, był mocno krytykowany za jego wydajność (był zły), ale to nie była tak naprawdę wina Swinga, to brak wiedzy ludzi na temat korzystania z niego.
SWT egzekwuje koncepcję bezpieczeństwa wątków, wprowadzając wyjątki, jeśli je naruszasz, nie jest to ładne, ale przynajmniej wiesz o tym.
Jeśli spojrzysz na przykład na proces malowania, bardzo ważna jest kolejność malowania elementów. Nie chcesz, aby malowanie jednego elementu powodowało efekt uboczny w jakiejkolwiek innej części ekranu. Wyobraź sobie, że możesz zaktualizować właściwość tekstu etykiety, ale została ona pomalowana przez dwa różne wątki, możesz uzyskać zepsuty wydruk. Więc całe malowanie odbywa się w ramach jednego wątku, zwykle w oparciu o kolejność wymagań / żądań (ale czasami skondensowane w celu zmniejszenia liczby faktycznych fizycznych cykli malowania)
Wspominasz o zmianie z Swing na JavaFX, ale miałbyś ten problem z praktycznie dowolnym frameworkiem interfejsu użytkownika (nie tylko z grubymi klientami, ale także z sieci), Swing wydaje się być tym, który podkreśla problem.
Możesz zaprojektować warstwę pośrednią (kontroler kontrolera?), Której zadaniem jest zapewnienie prawidłowej synchronizacji wywołań interfejsu użytkownika. Z perspektywy interfejsu API interfejsu użytkownika nie można dokładnie wiedzieć, jak zaprojektować części interfejsu API niezwiązane z interfejsem użytkownika, a większość programistów narzekałaby, że ochrona wątków zaimplementowana w interfejsie API interfejsu użytkownika była restrykcyjna lub nie spełniała ich potrzeb. Lepiej pozwolić ci zdecydować, jak chcesz rozwiązać ten problem, w zależności od twoich potrzeb
Jednym z największych problemów, które należy wziąć pod uwagę, jest możliwość uzasadnienia określonej kolejności zdarzeń na podstawie znanych danych wejściowych. Na przykład, jeśli użytkownik zmieni rozmiar okna, model Kolejki zdarzeń gwarantuje, że wystąpi określona kolejność zdarzeń, może się to wydawać proste, ale jeśli kolejka zezwoli na wywołanie zdarzeń przez inne wątki, nie można już zagwarantować kolejności w które zdarzenia mogą się zdarzyć (warunek wyścigu) i nagle musisz zacząć martwić się o różne stany i nie robić jednej rzeczy, dopóki coś innego się nie wydarzy i zaczniesz dzielić flagi państwowe i skończysz spaghetti.
OK, możesz rozwiązać ten problem, mając jakąś kolejkę, która uporządkowała wydarzenia na podstawie czasu ich wydania, ale czy to nie to, co już mamy? Poza tym nadal nie można zagwarantować, że wątek B wygeneruje zdarzenia PO wątku A.
Głównym powodem, dla którego ludzie denerwują się na myśl o swoim kodzie, jest to, że zmuszeni są myśleć o swoim kodzie / projekcie. „Dlaczego to nie może być prostsze?” To nie może być prostsze, ponieważ nie jest to prosty problem.
Pamiętam, kiedy PS3 zostało wydane, a Sony rozmawiało z procesorem Cell i jego zdolnością do wykonywania oddzielnych linii logicznych, dekodowania dźwięku, wideo, ładowania i rozwiązywania danych modelu. Jeden z twórców gier zapytał: „To niesamowite, ale jak synchronizować strumienie?”
Problem, o którym mówił deweloper, w pewnym momencie wszystkie te osobne strumienie musiały być zsynchronizowane w dół do pojedynczego potoku dla wyjścia. Biedny prezenter po prostu wzruszył ramionami, ponieważ nie był to znany im problem. Oczywiście mieli już rozwiązania tego problemu, ale w tamtych czasach było to zabawne.
Współczesne komputery pobierają wiele danych wejściowych z wielu różnych miejsc jednocześnie, wszystkie dane wejściowe muszą zostać przetworzone i dostarczone użytkownikowi z dala, co nie zakłóca prezentacji innych informacji, więc jest to złożony problem, bez jedno proste rozwiązanie.
Teraz, mając możliwość przełączania frameworków, nie jest to łatwe do zaprojektowania, ALE, weźmy MVC na chwilę, MVC może być wielowarstwowa, to znaczy, możesz mieć MVC, która zajmuje się bezpośrednio zarządzaniem frameworkiem UI, mógłby następnie owinąć to, że w MVC wyższej warstwy, która zajmuje się interakcjami z innymi (potencjalnie wielowątkowymi) strukturami, to ta warstwa będzie odpowiedzialna za określenie, w jaki sposób niższa warstwa MVC jest powiadamiana / aktualizowana.
Następnie użyłbyś kodowania do połączenia wzorców projektowych i wzorców fabrycznych lub konstruktorów do budowy tych różnych warstw. Oznacza to, że szkielety wielowątkowe zostają odłączone od warstwy interfejsu użytkownika poprzez użycie warstwy środkowej, jako pomysłu.