Il y a quelque temps, j'ai lu un très bon blog qui traitait de cette question (mentionnée par Karl Bielefeldt). En gros, il est très dangereux d'essayer de sécuriser le thread du kit d'interface utilisateur, car il introduit des impasses et en fonction de mis en œuvre, conditions de course dans le cadre.
Il y a aussi une considération de performance. Pas tellement maintenant, mais lorsque Swing a été publié, il a été vivement critiqué pour ses performances (été médiocre), mais ce n’est pas vraiment sa faute, c’est le manque de connaissances des personnes quant à son utilisation.
SWT applique le concept de sécurité des threads en générant des exceptions si vous le violez, pas beau, mais au moins, vous en êtes conscient.
Si vous regardez dans le processus de peinture, par exemple, l'ordre dans lequel les éléments sont peints est très important. Vous ne voulez pas que la peinture d'un composant ait un effet secondaire sur une autre partie de l'écran. Imaginez que si vous pouviez mettre à jour la propriété text d'une étiquette, mais que celle-ci ait été peinte par deux threads différents, vous pourriez vous retrouver avec une sortie corrompue. Ainsi, toute la peinture est faite dans un seul fil, normalement basé sur l'ordre des exigences / demandes (mais parfois condensé pour réduire le nombre de cycles de peinture physiques réels)
Vous avez parlé de passer de Swing à JavaFX, mais vous auriez ce problème avec à peu près n'importe quel framework d'interface utilisateur (pas seulement les clients lourds, mais également avec le Web). Swing semble être celui qui met en évidence le problème.
Vous pouvez concevoir une couche intermédiaire (contrôleur d’un contrôleur?) Chargée de s’assurer que les appels vers l’UI sont correctement synchronisés. Il est impossible de savoir exactement comment vous pourriez concevoir des parties de votre API non-UI du point de vue de l'API UI et la plupart des développeurs se plaindraient du fait que la protection de thread implémentée dans l'API UI était trop restrictive ou ne répondait pas à leurs besoins. Mieux vaut vous permettre de décider comment vous voulez résoudre ce problème, en fonction de vos besoins
L'un des problèmes les plus importants à prendre en compte est la capacité de justifier un ordre d'événements donné, en fonction d'entrées connues. Par exemple, si l'utilisateur redimensionne la fenêtre, le modèle File d'attente d'événements garantit qu'un ordre donné d'événements se produira. Cela peut sembler simple. Toutefois, si la file d'attente permettait aux événements d'être déclenchés par d'autres threads, vous ne pouvez plus garantir l'ordre les événements peuvent se produire (une situation de concurrence) et tout d'un coup, vous devez commencer à vous soucier de différents états et à ne rien faire jusqu'à ce que quelque chose d'autre se produise et que vous commenciez à devoir partager des drapeaux d'état et que vous vous retrouviez avec des spaghettis.
Ok, vous pouvez résoudre ce problème en ayant une sorte de file d'attente qui ordonne les événements en fonction de l'heure à laquelle ils ont été publiés, mais n'est-ce pas ce que nous avons déjà? En outre, vous ne pouvez toujours pas garantir que le thread B générera ses événements APRES le thread A
La principale raison pour laquelle les gens s'énervent à l'idée de penser à leur code, c'est parce qu'ils sont amenés à penser à leur code / design. "Pourquoi ça ne peut pas être plus simple?" Cela ne peut pas être plus simple, car ce n'est pas un problème simple.
Je me souviens de la sortie de la PS3 et du fait que Sony parlait du processeur Cell et de sa capacité à exécuter des lignes de logique distinctes, à décoder le son, la vidéo, à charger et à résoudre les données du modèle. Un développeur de jeux a demandé: "C'est génial, mais comment synchronisez-vous les flux?"
Le problème dont parlait le développeur était qu’à un moment donné, tous ces flux distincts devaient être synchronisés sur un seul canal de sortie. Le pauvre présentateur haussa simplement les épaules car ce n'était pas un problème qu'ils connaissaient bien. De toute évidence, ils ont eu des solutions pour résoudre ce problème maintenant, mais c'est amusant à l'époque.
Les ordinateurs modernes prennent beaucoup de données simultanément de nombreux endroits différents. Toutes ces données doivent être traitées et transmises à l'utilisateur de manière à ne pas gêner la présentation d'autres informations. Il s'agit donc d'un problème complexe, sans une seule solution simple.
Maintenant, avoir la possibilité de changer de framework, ce n’est pas une chose facile à concevoir, MAIS, prenons MVC un instant, MVC peut être multi-couches, c’est-à-dire que vous pourriez avoir un MVC qui traite directement de la gestion du framework d’interface utilisateur. pourrait alors envelopper le fait que, dans une couche supérieure MVC qui traite des interactions avec d'autres frameworks (potentiellement multi-threadés), il serait de la responsabilité de cette couche de déterminer comment la couche MVC inférieure est notifiée / mise à jour.
Vous utiliseriez ensuite le codage pour interfacer les modèles de conception et les modèles d'usine ou de générateur pour construire ces différentes couches. Cela signifie que vos frameworks multithreads sont découplés de la couche d'interface utilisateur via l'utilisation d'une couche intermédiaire, en tant qu'idée.