2011-07-04 27 views
33

Cosa fa SwingUtilities.invokeLater? È solo ritardare l'esecuzione di un blocco di codici all'interno del suo metodo run? Qual è la differenza tra chiamare un'azione all'interno della funzione invokeLater o semplicemente chiamarla alla fine del thread che si desidera eseguire? Qualcuno può aiutarmi con cosa fa realmente la funzione invokeLater?Cosa fa SwingUtilities.invokeLater?

+0

Vedere anche http://stackoverflow.com/questions/5780936/java-eventqueue-why-should-everything-be-in-invokelater-method per background (background correlato, ma non un duplicato). –

+0

Cerca Swing EDT su Google. –

risposta

20

Come altre risposte hanno detto, esegue il tuo sul thread di invio eventi AWT. Ma perché vorresti farlo? Poiché le strutture dati di Swing non sono thread-safe, quindi per fornire ai programmatori un modo facilmente raggiungibile di impedire l'accesso simultaneo ad esse, i progettisti di Swing hanno stabilito la regola che tutto il codice che le accede deve essere eseguito sullo stesso thread. Ciò avviene automaticamente per la gestione degli eventi e il codice di manutenzione del display, ma se hai avviato un'azione a lungo termine - su un nuovo thread, ovviamente - come puoi segnalarne il progresso o il completamento? Devi modificare un controllo Swing e devi farlo dal thread di invio dell'evento. Quindi invokeLater.

+0

OOH! quindi è così che puoi fare un singolo threading asincrono in java! È strano che debba essere fornito in bundle con un kit di strumenti "Windowing", sembra un po 'fuori luogo. – Dmitry

+2

@Dmitry Questo è un modo divertente per guardarlo. Java non fornisce supporto a livello di lingua per il single-threading (fa una qualsiasi lingua?). Quindi un framework che lo richiede deve fornire funzionalità per supportarlo e stabilire regole per il programmatore del client per usarlo correttamente. Questo non è "Il modo Java di farlo", piuttosto è un modo per farlo in Java. –

8

Verrà eseguito il pezzo di codice sul thread AWT. Che ti permette di modificare la GUI da altri thread.

Da Docs:

Provoca doRun.run() per essere eseguito in modo asincrono sull'evento AWT dispacciamento thread. Ciò si verificherà dopo che tutti gli eventi AWT in sospeso sono stati elaborati . Questo metodo deve essere utilizzato quando un thread dell'applicazione deve aggiornare GUI.

2

che è sarebbe commento, ma si presenta come il più a lungo ..., solo roba di base

1/creare proprio EDT per il corretto aggiornamento della GUI, f.e. se si è eseguito del codice utilizzando plain vanilla Thread, java.util.Timer, Executor .. Altre here

2/aiuta con il set Focus al JComponents IOF ci sono alcuni Listeners perché se c'è f.e. DocumentListener poi difficile impostare Focus alle JComponents esecuzioni codice

3/ritardo desiderato bloccare e spostare che alle estremità di EDT

2

come già notato, invokeLater consente di chiamare sicuro metodi in classi battente quando si è non funziona su EventQueue per cominciare. Tuttavia, puoi semplificare il tuo codice e la tua vita accedendo ad altri campi e classi solo da da EventQueue. Possono lavorare con swing e l'altro senza tutti i fastidi del multi-threading. Se hai avviato un'altra discussione, utilizza InvokeLater per tornare a EventQueue il più rapidamente possibile e ridurre al minimo il numero di campi che devono essere sincronizzati o altrimenti protetti.

Se è necessario sfruttare al massimo i core multipli, è necessario ridurre l'utilizzo di EventQueue e si dovrà pagare un grande prezzo in termini di complessità.

1

Si noti che alla fine si riceve una chiamata al metodo doRun.run() per ogni volta che si chiama invokeLater (doRun) per. Quindi, se lo chiami dieci volte prima che il thread dell'evento ottenga l'opportunità di eseguire l'elaborazione, è probabile che tu riceva dieci chiamate successive a doRun.run().