IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

EDT/SwingWorker Java Discussion :

[debutant] quand l'EDT est-il lancé ?


Sujet :

EDT/SwingWorker Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Modérateur
    Avatar de nouknouk
    Homme Profil pro
    Inscrit en
    Décembre 2006
    Messages
    1 655
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Par défaut [debutant] quand l'EDT est-il lancé ?
    Bonjour à tous,

    une petite question de (gros) débutant en Java : voilà, je me demandais quand est-ce que l'EDT était lancé et s'il l'était systématiquement pour toute nouvelle application

    Le contexte:
    Pour mieux situer mes questions, je précise que je suis un développeur confirmé en C++ avec Qt. Je me mets doucement au Java et je cherche a faire un parallèle entre la boucle d'événements gérée par l'event loop de Qt et l'EDT dans Java (si parallèle il y a).

    Le cas pratique :
    Plus précisément : je susi en train de développer une classe FrameSocket, capable de communiquer en TCP avec une autre FrameSocket en envoyant et recevant des 'frames' ( <=> des paquets de données avec un format perso prédéfini).

    Chaque instance de ma tite classe lance donc son propre thread pour attendre, lire les données les données reçues et en extraire la substantielle moelle (entendez par là désérialiser mes types de données perso).

    Ce que je voudrais maintenant implémenter c'est un mécanisme d'event + listeners qui va émettre un event lorsque :
    - la connection a été perdue
    - une nouvelle frame a été reçue et désérialisée.

    Après quelques lectures (merci aux tutos de ce site !) je pense que poster les événements dans l'EDT est le meilleur moyen pour arriver à mes fins puisque logiquement, dans le cas d'une appli avec UI ces événements (ainsi que ceux générés par l'UI) seront à l'origine des changements de mon modèle et de l'UI elle même.

    La question :
    La question que je me pose : est-ce que l'EDT est un thread ... euhm ... disons ... "principal" ... qui est systématiquement lancé à chaque démarrage d'application et d'applet, même lorsqu'une l'application n'utilise pas d'UI ?
    (en d'autres termes, le jour où je réutiliserai ma FrameSocket dans une autre appli, serai-je sûr que je peux compter sur la présence de l'EDT ?)

    Question subsidiaire (si la première réponse est affirmative): si une application n'utilise pas d'UI, mais qu'elle a un fonctionnement événementiel, un développeur java utilisera-t-il systématiquement l'EDT pour gérer ses événements ? (avec invokeLAter, invokeAndWait, ...)
    Typiquement, mon serveur avec 15 clients connectés aura 15 FrameSockets instanciées (donc 15 threads) et le modèle + controller sera géré par l'EDT ?
    Y a-t-il d'autres façon de faire avec leurs avantages (sans réinventer la roue inutilement) ?

    Dernière question (pour la route, et si je vous ai pas encore assez ennuyé avec mes questions bêtes) : Avec Qt par exemple, le thread principal qui gère l'event loop est simplement le thread principal de l'appli. On a quelque chose dans le genre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    int main(int argc, char** argv) {
      QApplication appli(argc,argv);
      appli.setMAinWindow(new MaWindow());
      return appli.exec();
    }
    Pourquoi il a été décidé en Java que le thread de l'EDT ne soit pas le même que le thread du main() ?



    Merci beaucoup d'avance pour vos précisions.

  2. #2
    Membre éclairé

    Profil pro
    Coach Agile
    Inscrit en
    Décembre 2005
    Messages
    316
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Coach Agile

    Informations forums :
    Inscription : Décembre 2005
    Messages : 316
    Par défaut
    Pour ta gestion d'événement, je te conseille http://rom.developpez.com/java-listeners/.

    Pour ce qui est de l'EDT, il est géré par la couche AWT. Il n'y a à mon sens aucune raison qu'il soit lancé dans une application sans IU.

    Je ne trouve donc pas opportun d'implémenter ta classe en exploitant des fonctions qui lui sont propres (invokeLAter, invokeAndWait ... d'ailleurs, il me semble que ces fonctions sont fournies par swing et non AWT).

    Chris.

  3. #3
    Modérateur
    Avatar de nouknouk
    Homme Profil pro
    Inscrit en
    Décembre 2006
    Messages
    1 655
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Par défaut
    salut,

    tou d'abord, merci pour tes réponses.

    - Concernant la notion d'observer, je connais bien le pattern et j'ai déjà lu le tuto que tu me proposes.

    - Concernant mon cas de figure, il est un peu particulier. Prenons le cas du serveur acceptant plusieurs connections, donc contient plusieurs instances de Socket qui peuvent recevoir à tout moment de nouvelles données à traiter.

    -> si j'ai 15 sockets, je ne peux pas me permettre de n'avoir qu'un seul thread bloqué par un socket.getInputStream().read() car je n'écouterais qu'un seul socket et pas les 14 autres.

    -> pour des raisons de performances, je ne peux pas non plus dire "je vais régulièrement itérer sur chacune des sockets et faire un socket.getInputStream().isAvailable() pour voir si j'ai quelque chose à lire". Ce serait de l'attente active et cela boufferait inutilement des ressources procs de mon serveur.

    => La seule solution qui me semble viable est d'instancier un thread dédié à chaque socket (appelons-les les "socket's threads"). Chacun d'eux fait un socket.getInputStream().read() et donc est endormi tant qu'il n'y a rien de nouveau à lire. Lorsque quelque chose arrive sur sa socket, il se réveille et récupère lesdites données.

    Le problème avec cette solution est qu'une fois que le thread de mon socket a récupéré les données d'une frame, il va avertir un listener pour effectuer le traitement approprié sur l'unique modèle de données du serveur. Ce modèle est commun à toutes les connexions.

    Souci: quel thread doit déclencher et effectuer l'action du listener ? Pour éviter un accès concurrent à mon modèle par plusieurs "socket's threads" en même temps, je ne peux pas faire effectuer l'action par le "socket's thread" lui même.
    Donc je me dis qu'il me faudrait un unique thread supplémentaire (appelons le "action thread") qui, lui, sera le seul à toucher aux données du modèle. les "socket threads" n'auront qu'à lui poster des événements quand il y a quelque chose à faire (d'ou les événements 'frame reçue'). Ainsi, je garantis l'absence de d'accès concurrent à mon modèle puisque chaque action sera exécutée séquentiellement.


    D'où l'idée d'utiliser l'EDT comme "action thread" puisque:

    - il implémente déjà la notion d'événements, d'event loop, de queue thread safe, etc... et les devs du SDK java ayant plus d'expé que moi, je leur fais plus confiance

    - AWT & Swing font partie du framework de base de java ( >= 1.2 si mes souvenirs sont bons). Donc ma classe serait réutilisable quel que soit la nouvelle application dans laquelle je voudrais l'utiliser.

    - l'EDT n'a pas nécessairement besoin d'une UI pour marcher, cf. ce code de test :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    import javax.swing.SwingUtilities;
     
    public class EdtTest {
    	public static void main(String[] args) {
    		System.out.println("avant l'EDT");
    		SwingUtilities.invokeLater( new Runnable() {
    			public void run() {
    				System.out.println("dans l'EDT");
    			}
    		});
    	}
    }
    // l'EDT est bien créé et effectue bien mon action
    // alors qu'aucune partie du framework pour l'UI n'a été utilisé.
    Vala vala ... j'ai tout faux docteur ?


    EDIT: ps: j'ai trouvé la réponse à ma première question : après quelques tests simples, il apparaît que l'EDT est créé de façon transparente la première fois qu'on a besoin de lui (instanciation d'une JFrame, 1er appel d'invokeLAter(), ...). Reste la question de savoir si ma démarche est globalement acceptable ou si c'est une hérésie totale .

  4. #4
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Salut,

    Citation Envoyé par nouknouk
    Reste la question de savoir si ma démarche est globalement acceptable ou si c'est une hérésie totale .
    Pour moi c'est un peut idiot d'utiliser l'EDT pour cela...

    Si tu utilises Java 5.0 tu peux utiliser le package java.util.concurrent qui te permettra de faire tout cela (et même plus de manière assez simple). Tu peux par exemple utiliser une BlockingQueue pour "passer" des données de tes "socket thread" vers ton "model thread"...


    Sinon tu peux utiliser des Collections synchronisé pour cela.

    a++

  5. #5
    Modérateur
    Avatar de nouknouk
    Homme Profil pro
    Inscrit en
    Décembre 2006
    Messages
    1 655
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Par défaut
    Citation Envoyé par adiGuba
    Si tu utilises Java 5.0 tu peux utiliser le package java.util.concurrent qui te permettra de faire tout cela (et même plus de manière assez simple).
    Ok, merci beaucoup pour l'info. J'avais pas encore vu ce package
    Je vais voir ce que je peux en retirer.

    Citation Envoyé par adiGuba
    Pour moi c'est un peut idiot d'utiliser l'EDT pour cela...
    Pourrais-tu préciser pourquoi exactement ? (EDT = usine à gaz ; pas 'conventionnel' ; ...).
    -> Perso, je me disais bêtement que dans le cas où ma class FrameSocket est utilisée dans une appli avec UI, ça permettrait justement de ne pas avoir un thread supplémentaire puisque l'EDT sera de toute façon nécessaire à l'UI...
    -> De plus, dans le cas de mon futur client qui utilisera ma FrameSocket, c'est la réception de frames qui sera à l'origine de presque tous les changements d'UI (update de la user list, ...)

    Plus globalement, quand un dev Java a besoin de gérer des événements (non graphiques) dans une appli, comment fait-il ?

  6. #6
    Expert confirmé
    Avatar de Baptiste Wicht
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2005
    Messages
    7 431
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Suisse

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2005
    Messages : 7 431
    Par défaut
    Citation Envoyé par nouknouk
    Plus globalement, quand un dev Java a besoin de gérer des événements (non graphiques) dans une appli, comment fait-il ?
    Il utilise le gestionnaire d'événements

    C'est très simple à faire, tu as un objet écouté qui posséde des écouteurs et dès qu'il le faut il avertit les écouteurs qui réagissent ensuite comme il le faut...

  7. #7
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par nouknouk
    Pourrais-tu préciser pourquoi exactement ? (EDT = usine à gaz ; pas 'conventionnel' ; ...).
    L'EDT doit servir uniquement à mettre à jour l'affichage.

    Si tu n'as pas de GUI, c'est bête de charger les différents composants graphiques pour simplement mettre à jour un modèle de données...

    Et si tu as une GUI, tu risque d'avoir des ralentissement à cause des traitements de gestion que tu ferais dans ton EDT.

    Citation Envoyé par nouknouk
    Plus globalement, quand un dev Java a besoin de gérer des événements (non graphiques) dans une appli, comment fait-il ?
    Il y a plusieurs moyens de faire : il faudrait avant tout connaitre tes besoins (quels évènements sont lancés, par qui, qui doit les traiter, comment, etc.)


    a++

Discussions similaires

  1. [IDE] Exécution ralentie quand RAD Studio n'est pas lancé
    Par kurul1 dans le forum C++Builder
    Réponses: 13
    Dernier message: 27/11/2013, 14h49
  2. Service de géolocalisation stoppé quand Google Map est lancé
    Par David55 dans le forum API standards et tierces
    Réponses: 0
    Dernier message: 02/10/2013, 16h44
  3. [AC-2003] Empêcher d'ouvrir une autre application quand la mienne est lancée
    Par flet le kid dans le forum VBA Access
    Réponses: 4
    Dernier message: 02/07/2009, 15h04
  4. Réponses: 9
    Dernier message: 08/12/2004, 15h36
  5. Savoir quand une hotkey est relachée
    Par kriterium dans le forum Composants VCL
    Réponses: 2
    Dernier message: 24/07/2004, 15h44

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo