Spiegazione del thread di invio eventi Java

Recentemente ho iniziato a studiare e ad esplorare le basi della programmazione GUI in Java.

Avendo programmato per un po ‘ho fatto solo il back-end di lavoro o di lavoro e di conseguenza il più vicino che ho ottenuto alle interfacce utente è la console di comando (imbarazzante lo so).

Sto usando Swing e per quanto posso raccogliere significa che per estensione sto usando AWT.

La mia domanda è basata su questo pezzo di codice:

java.awt.EventQueue.invokeLater(new Runnable() { public void run() { new frame.setVisible(true); } } ); 

Ho cercato questo per un po ‘perché volevo comprendere appieno questo strano pezzo di codice e ho trovato il termine “Thread di invio di eventi” più volte. Correggimi se sbaglio, ma a quanto capisco; ha a che fare con l’utilizzo di più thread e come Java Swing interpreta quei thread. Trovo anche che il codice sopra sia usato per assicurarci che tutti i thread siano “sicuri” prima di creare la finestra, da qui il richiamo?

Ho letto che:

“Puoi solo chiamare i metodi che operano sul frame dal thread di invio degli eventi”

e che solo in determinate circostanze puoi chiamare metodi che operano sul frame dal metodo principale.

Qualcuno può chiarirmi per favore qual è esattamente il thread di invio degli eventi?

Come si relaziona a più thread di esecuzione e come questi thread non sono sicuri da chiamare dal metodo principale? Inoltre, perché abbiamo bisogno di questo invokeLater?

Non possiamo semplicemente creare la finestra come qualsiasi altro object?

Ho centrato un pò di strada nella mia ricerca perché non sto cogliendo queste relazioni e idee.

Una nota a margine è che mi piace basare le mie conoscenze su una comprensione approfondita poiché credo che ciò porti al miglior risultato complessivo e di conseguenza ai migliori programmi. Se capisco in modo approfondito come funziona qualcosa, allora puoi usare i suggerimenti e le modifiche in modo efficace piuttosto che semplicemente riprenderli a codice, quindi per favore non aver paura di darmi delle spiegazioni approfondite extra e ampliare le mie conoscenze.

Grazie.

Il thread EventDispatching è un thread speciale gestito da AWT. Fondamentalmente si tratta di un thread che viene eseguito in un evento di elaborazione loop infinito. Il metodo java.awt.EventQueue.invokeLater è un modo speciale per fornire del codice che verrà eseguito sulla coda degli eventi. Scrivere un framework ui sicuro in un ambiente di multithreading è molto difficile, quindi gli autori di AWT hanno deciso che avrebbero consentito solo operazioni su oggetti GUI su un singolo thread speciale. Tutti i gestori di eventi verranno eseguiti su questo thread e tutto il codice che modifica il gui dovrebbe funzionare anche su questo thread.

Ora l’AWT di solito non controlla che non si stiano impartendo comandi GUI da un altro thread (il framework WPF per C # lo fa). quindi è ansible scrivere molto codice ed essere praticamente agnostici a questo e non incorrere in alcun problema. Ma questo può portare a comportamenti non definiti, quindi la cosa migliore da fare è assicurarsi sempre che il codice GUI sia eseguito sul thread del dispatcher dell’evento. invokeLater fornisce un meccanismo per farlo.

Quindi un esempio classico è che è necessario eseguire un’operazione di lunga durata come scaricare un file. Quindi si avvia una discussione per eseguire questa azione, quindi una volta completata si utilizzerà invokeLater per aggiornare l’interfaccia utente. Se non hai usato invokeLater e invece hai appena aggiornato direttamente l’interfaccia utente, potresti avere una race condition e potrebbe verificarsi un comportamento indefinito.

Wikipedia ha più informazioni: http://en.wikipedia.org/wiki/Event_dispatching_thread

Inoltre, se sei curioso di sapere perché gli autori di awt non fanno solo il toolkit multithread qui, è un buon articolo: https://community.oracle.com/blogs/kgh/2004/10/19/multithreaded-toolkits-failed-dream

EventDispatchThread (EDT) è un thread speciale riservato solo alla GUI di Swing e agli eventi correlati di * Swing, ad esempio crea / modifica / aggiorna Swing JComponents , altro per le domande poste qui e qui

tutti gli output della GUI da BackGround Tasks , i Runnable#Thread eseguibili devono essere racchiusi in invokeLater () , da oggetti sincronizzati in invokeAndWait();