web-dev-qa-db-fra.com

Java Explication du thread de répartition des événements

J'ai récemment commencé à apprendre et à explorer les bases de la programmation GUI en Java.

Après avoir programmé pendant un certain temps, je n'ai fait que du backend ou du travail et, par conséquent, le plus proche des interfaces utilisateur est la console de commande (embarrassante je sais).

J'utilise Swing et pour autant que je puisse en déduire que par extension j'utilise également AWT.

Ma question est basée sur ce morceau de code:

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

Je fais des recherches sur ce sujet depuis un certain temps, car je voulais comprendre pleinement cet étrange morceau de code et j'ai rencontré le terme 'Event-Dispatching Thread' plusieurs fois. Corrigez-moi si je me trompe mais si je comprends bien; cela a à voir avec l'utilisation de plusieurs threads et comment Java Swing interprète ces threads. Je suppose également que le code ci-dessus est utilisé pour s'assurer que tous les threads sont "sûrs" avant de créer la fenêtre , d'où l'invokeLater?

J'ai lu cela:

"Vous ne pouvez appeler que les méthodes qui opèrent sur le cadre à partir du thread de répartition des événements"

et que ce n'est que dans certaines circonstances que vous pouvez appeler des méthodes qui opèrent sur le cadre à partir de la méthode principale.

Quelqu'un peut-il me préciser ce qu'est exactement le fil de répartition des événements?

Comment cela se rapporte-t-il à plusieurs threads d'exécution et comment ces threads ne peuvent pas être appelés à partir de la méthode principale? Aussi pourquoi avons-nous besoin de cet invokeLater?

Ne pouvons-nous pas simplement créer la fenêtre comme n'importe quel autre objet?

J'ai un peu bloqué mes recherches car je ne saisis pas ces relations et ces idées.

Une note secondaire est que j'aime baser mes connaissances sur une compréhension approfondie car je crois que cela conduit au meilleur résultat global et, par conséquent, aux meilleurs programmes. Si je comprends en détail comment quelque chose fonctionne, vous pouvez utiliser les conseils et les ajustements efficacement plutôt que de simplement les renvoyer en code, alors n'hésitez pas à me donner des explications supplémentaires et à élargir mes connaissances.

Je vous remercie.

54
linuscash

thread de distribution d'événements est un thread spécial géré par AWT. Fondamentalement, c'est un thread qui s'exécute dans une boucle infinie, traitant les événements.

Le Java.awt.EventQueue.invokeLater et javax.swing.SwingUtilities.invokeLater Les méthodes sont un moyen de fournir du code qui s'exécutera sur la file d'attente des événements. Il est très difficile d'écrire un cadre d'interface utilisateur sûr dans un environnement multithreading, de sorte que les auteurs de l'AWT ont décidé qu'ils autoriseraient uniquement les opérations sur les objets GUI sur un seul thread spécial. Tous les gestionnaires d'événements s'exécuteront sur ce thread et tout le code qui modifie l'interface graphique devrait également fonctionner sur ce thread.

Maintenant, AWT ne vérifie généralement pas que vous n'émettez pas de commandes GUI à partir d'un autre thread (le cadre WPF pour C # le fait), ce qui signifie qu'il est possible d'écrire beaucoup de code et d'être à peu près agnostique à cela et de ne rencontrer aucun problème. Mais cela peut conduire à un comportement indéfini, donc la meilleure chose à faire est de toujours s'assurer que le code GUI s'exécute sur le thread de répartition des événements. invokeLater fournit un mécanisme pour ce faire.

Un exemple classique est que vous devez exécuter une opération longue comme le téléchargement d'un fichier. Vous lancez donc un thread pour effectuer cette action, puis, lorsqu'elle est terminée, vous utilisez invokeLater pour mettre à jour l'interface utilisateur. Si vous n'avez pas utilisé invokeLater et que vous venez de mettre à jour l'interface utilisateur directement, vous pouvez avoir une condition de concurrence critique et un comportement non défini peut se produire.

Wikipedia a plus d'informations

De plus, si vous êtes curieux de savoir pourquoi les auteurs d'AWT ne font pas que la boîte à outils multithread, ici est un bon article.

59
luke

EventDispatchThread (EDT) est un thread spécial réservé uniquement à Swing GUI et * aux événements liés à Swing, par exemple créer/changer/mettre à jour Swing JComponents , plus pour les questions posées ici et ici

toutes les sorties vers l'interface graphique à partir de BackGround Tasks, Runnable#Thread doivent être enveloppées dans invokeLater () , des objets synchronisés dans invokeAndWait();

12
mKorbel