Qualche tempo fa ho letto un ottimo blog che discute di questo problema (menzionato da Karl Bielefeldt), quello che dice in sostanza è che è molto pericoloso provare a rendere sicuro il thread del kit UI, poiché introduce possibili deadlock e dipende da come è implementato, condizioni di gara nel quadro.
C'è anche una considerazione delle prestazioni. Non molto ora, ma quando Swing è stato rilasciato per la prima volta è stato fortemente criticato per le sue prestazioni (è stato un male), ma non è stata davvero colpa di Swing, è stata la mancanza di conoscenza delle persone su come usarlo.
SWT applica il concetto di sicurezza del thread generando eccezioni se lo violate, non è carino, ma almeno ne siete consapevoli.
Se osservi il processo di verniciatura, ad esempio, l'ordine in cui gli elementi sono dipinti è molto importante. Non vuoi che il dipinto di un componente abbia un effetto collaterale su qualsiasi altra parte dello schermo. Immagina di poter aggiornare la proprietà text di un'etichetta, ma è stata dipinta da due thread diversi, potresti finire con un output danneggiato. Quindi tutta la verniciatura viene eseguita all'interno di un singolo filo, normalmente basato sull'ordine dei requisiti / richieste (ma a volte condensato per ridurre il numero di cicli di verniciatura fisici effettivi)
Dici di cambiare da Swing a JavaFX, ma avresti questo problema con praticamente qualsiasi framework dell'interfaccia utente (non solo client spessi, ma anche web), Swing sembra proprio essere quello che evidenzia il problema.
È possibile progettare un livello intermedio (un controller di un controller?) Il cui compito è garantire che le chiamate all'interfaccia utente siano sincronizzate correttamente. È impossibile sapere esattamente come potresti progettare le parti non UI della tua API dal punto di vista dell'API UI e la maggior parte degli sviluppatori si lamenterebbe che qualsiasi protezione thread implementata nell'API UI fosse restrittiva o non soddisfaceva le loro esigenze. Meglio consentirti di decidere come risolvere questo problema, in base alle tue esigenze
Uno dei maggiori problemi che devi considerare è la capacità di giustificare un determinato ordine di eventi, sulla base di input noti. Ad esempio, se l'utente ridimensiona la finestra, il modello Coda eventi garantisce che si verifichi un determinato ordine di eventi, questo potrebbe sembrare semplice, ma se la coda consentiva agli eventi di essere attivati da altri thread, non è più possibile garantire l'ordine in quali eventi potrebbero verificarsi (una condizione di gara) e all'improvviso devi iniziare a preoccuparti di diversi stati e non fare una cosa finché non succede qualcos'altro e inizi a dover condividere bandiere di stato in giro e finisci con gli spaghetti.
Ok, potresti risolverlo avendo una specie di coda che ordina gli eventi in base al momento in cui sono stati emessi, ma non è quello che già abbiamo? Inoltre, non puoi ancora garantire che il thread B genererà i suoi eventi DOPO il thread A
Il motivo principale per cui le persone si arrabbiano nel dover pensare al proprio codice è perché sono costretti a pensare al proprio codice / design. "Perché non può essere più semplice?" Non può essere più semplice, perché non è un problema semplice.
Ricordo quando è stata rilasciata la PS3 e Sony parlava del processore Cell ed è in grado di eseguire linee separate di logiche, decodificare audio, video, caricare e risolvere i dati del modello. Uno sviluppatore di giochi ha chiesto: "È tutto fantastico, ma come si sincronizzano i flussi?"
Il problema di cui parlava lo sviluppatore era, ad un certo punto, che tutti quei flussi separati avrebbero dovuto essere sincronizzati su un singolo tubo per l'output. Il povero presentatore si strinse semplicemente nelle spalle perché non era un problema a loro familiare. Ovviamente, hanno avuto soluzioni per risolvere questo problema ora, ma al momento è divertente.
I computer moderni stanno ricevendo contemporaneamente molti input da molti luoghi diversi, tutti gli input devono essere elaborati e consegnati all'utente in remoto, il che non interferisce con la presentazione di altre informazioni, quindi è un problema complesso, senza un'unica soluzione semplice.
Ora, avendo la possibilità di cambiare framework, non è una cosa facile da progettare, MA prendi MVC per un momento, MVC può essere multistrato, cioè potresti avere un MVC che si occupa direttamente della gestione del framework UI, tu potrebbe quindi concludere che, ancora una volta, in un MVC di livello superiore che si occupa delle interazioni con altri framework (potenzialmente multi threaded), sarebbe responsabilità di questo layer determinare come viene notificato / aggiornato il layer MVC inferiore.
Dovresti quindi utilizzare la codifica per interfacciare i modelli di progettazione e i modelli di fabbrica o di costruzione per costruire questi diversi livelli. Ciò significa che i framework multithread vengono disaccoppiati dal livello dell'interfaccia utente attraverso l'uso di un livello intermedio, come idea.