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

avec Java Discussion :

Threads et synchronisation


Sujet :

avec Java

  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2011
    Messages
    442
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2011
    Messages : 442
    Points : 417
    Points
    417
    Par défaut Threads et synchronisation
    Bonjour,

    Je suis débutant sur les threads, et j'aurais besoin d'une petite aide :

    J'ai un thread 1 qui crée une interface graphique, et un Thread 2 qui charge des données utilisateur. Quand les deux tâches sont finies, il faut charger le profil dans l'interface. Comment je suis sensé faire pour faire ça de façon propre ?

    La solution que j'utilise actuellement c'est ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    //thread 1
    //traitements...
    if(!interfaceReady) {chargementEnAttente = true; }//
    else {chargement();}
     
     
    //thread 2
    //traitements...
    interfaceReady = true;
    if(chargementEnAttente) {chargement();}
    Mais ça me parait pas fou...

    Merci de votre aide

  2. #2
    Membre éclairé Avatar de JoeChip
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    536
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2008
    Messages : 536
    Points : 803
    Points
    803
    Par défaut
    Pourquoi faire ça avec 2 threads ?
    Sans danger si utilisé conformément au mode d'emploi.

    (anciennement BenWillard, enfin moins anciennement que ... enfin bon c'est une longue histoire... Un genre de voyage dans le temps...)

  3. #3
    Expert éminent sénior
    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
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Salut,


    De quel type d'interface graphique s'agit-il ?
    Par exemple Swing tu peux utiliser un SwingWorker pour cela...


    a++

  4. #4
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2011
    Messages
    442
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2011
    Messages : 442
    Points : 417
    Points
    417
    Par défaut
    Citation Envoyé par JoeChip Voir le message
    Pourquoi faire ça avec 2 threads ?
    Parce que comme ça, pendant que l'utilisateur choisit quel fichier il veut ouvrir, crée un nouveau fichier, etc, je peux charger toute l'interface, les icônes, etc. Ca fait gagner du temps.

    Par exemple Swing tu peux utiliser un SwingWorker pour cela...
    Jamais entendu parler. Mais cool, je vais regarder ça. Merci bien !

  5. #5
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Sauf que:

    choisir un fichier ne nécessite pas de thread particulier: tu va charger le fichier en réaction au clic sur l'icone du fichier, donc dans le thread de l'EDT (quitte à utilise un swingworker après pour la partie lente de parsing du fichier)

    Charger l'interface (icone, création de fenetre, boutons, etc), ça doit aussi se faire dans l'EDT....

  6. #6
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2011
    Messages
    442
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2011
    Messages : 442
    Points : 417
    Points
    417
    Par défaut
    En fait, mon problème, c'est que je sais pas quel Thread aura fini le premier, et que pour passer à la suite, les deux doivent avoir terminé. Au final, je n'ai pas trouvé mieux que d'utiliser 1 ou 2 boolean volatile et à la fin de chaque thread, vérifier que l'autre a fini, comme j'ai montré dans mon premier post. Je pense que si j'avais plus de Thread, la meilleure solution serait d'avoir un objet type manager qui soit appelé à la fin de chaque thread. Quand il a été appelé par tous les Threads qu'il attendait, il lance la suite. Un truc du style

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public class Manager {
        private PredefinedInterface callback;
        private volatile Map<Integer, Boolean> finished;
        public Manager(PredefinedInterface callback, int[] threadIDs) {
            this.callback = callback;
            for(int id : threadIDs) {
                 finished.put(id,false);
            }
        }
        public void finished(int id, String msg) {
             if(msg.equals("done")) {finished.put(id,true);}
             if(!finished.containsValue(false)) {callback.callMethod();}
        }
    }
    Qu'est-ce que vous en pensez ?

  7. #7
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2011
    Messages
    442
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2011
    Messages : 442
    Points : 417
    Points
    417
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    Charger l'interface (icone, création de fenetre, boutons, etc), ça doit aussi se faire dans l'EDT....
    Ah bon ? Pourquoi ? Tant que je n'ai pas fait setVisible, pourquoi je ne pourrais pas préparer tranquillement mon interface dans un Thread secondaire pendant que j'utilise l'EDT pour faire patienter l'utilisateur ?

    Citation Envoyé par tchize_ Voir le message
    choisir un fichier ne nécessite pas de thread particulier: tu va charger le fichier en réaction au clic sur l'icone du fichier, donc dans le thread de l'EDT (quitte à utilise un swingworker après pour la partie lente de parsing du fichier)
    Là encore, je mentionnais
    un Thread 2 qui charge des données utilisateur
    Donc, justement, il va, entre autre faire du parsing de fichier, des initialisations dans le modèle, etc. Rien qui, à mon sens, ne nécessite à priori de figurer dans l'EDT.

    Par contre, une fois ces deux Threads terminés, je veux rejoindre l'EDT, charger le modèle dans l'interface et faire setVisible(true) sur mon interface

    C'est pas bon ?

  8. #8
    Membre éclairé Avatar de JoeChip
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    536
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2008
    Messages : 536
    Points : 803
    Points
    803
    Par défaut
    Alors tu dois mettre le ready à true à la fin du traitement dans le thread, non avant le "if'
    Sans danger si utilisé conformément au mode d'emploi.

    (anciennement BenWillard, enfin moins anciennement que ... enfin bon c'est une longue histoire... Un genre de voyage dans le temps...)

  9. #9
    Expert éminent sénior
    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
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Sharcoux Voir le message
    Qu'est-ce que vous en pensez ?
    Je ne sais pas !
    Tu nous expliques comment tu fais... mais on ne sait rien de l'objectif de tout cela !


    Bref : que veux tu faire ?


    a++

  10. #10
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Citation Envoyé par Sharcoux Voir le message
    Ah bon ? Pourquoi ? Tant que je n'ai pas fait setVisible, pourquoi je ne pourrais pas préparer tranquillement mon interface dans un Thread secondaire pendant que j'utilise l'EDT pour faire patienter l'utilisateur ?
    Dans les doc mentionnant qu'on ne dois pas manipuler un composant swing en dehors de l'EDT, je n'ai jamais vu mentionné 'sauf si il n'est pas visible', mais admettons. Tu peux très bien utiliser le swingworker pour tout ce que tu mentionne.

    Il va falloir être un peu plus explicite sur ce qui est "long" dans la création de ton interface, les solutions varient suivant ce qui pose problème. La lecture du fichier, elle, peux se faire dans le swingworker.


    Enfin, d'un manière générale, pour attendre qu'un thread aie fini, pas besoin de variable, un simple thread.join() fait l'affaire.

  11. #11
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2011
    Messages
    442
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2011
    Messages : 442
    Points : 417
    Points
    417
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    Enfin, d'un manière générale, pour attendre qu'un thread aie fini, pas besoin de variable, un simple thread.join() fait l'affaire.
    Ah! J'avais pas du tout compris que ça marchait comme ça "join()". C'est ça la solution. C'est ça que j'essayais d'imiter avec le Manager. La problématique c'était juste de faire en sorte que les Threads s'attendent l'un l'autre. Du coup mon Manager deviendrait tout simplement :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    public static attendre(Threads[] threads) {
            for(Thread t : threads) {
               try {
                  t.join () ;
               } catch (InterruptedException e) {
                  System.out.println ("InterruptedException sur " + c [i].nom ()) ;
               }
            }
        }
    Ce qui me parait plus sain.

    Citation Envoyé par tchize_ Voir le message
    Dans les doc mentionnant qu'on ne dois pas manipuler un composant swing en dehors de l'EDT, je n'ai jamais vu mentionné 'sauf si il n'est pas visible', mais admettons. Tu peux très bien utiliser le swingworker pour tout ce que tu mentionne.
    Ah ? Ok, je pensais pas que ça posait problème comme je ne faisais qu'initialiser l'interface. Par contre si je prépare mon interface dans le doInBackground() d'un SwingWorker et que je l'affiche dans le done(), c'est bon, c'est ça ?

    Citation Envoyé par tchize_ Voir le message
    Il va falloir être un peu plus explicite sur ce qui est "long" dans la création de ton interface, les solutions varient suivant ce qui pose problème. La lecture du fichier, elle, peux se faire dans le swingworker.
    Essentiellement la création des boutons avec le chargement de toutes les icônes. La création d'un JTextPane aussi prend un temps assez conséquent, mais je n'ai pas trouvé pourquoi. Peut-être le chargement des librairies associées.

    Merci à tous !

  12. #12
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Citation Envoyé par Sharcoux Voir le message


    Ah ? Ok, je pensais pas que ça posait problème comme je ne faisais qu'initialiser l'interface. Par contre si je prépare mon interface dans le doInBackground() d'un SwingWorker et que je l'affiche dans le done(), c'est bon, c'est ça ?
    On peux imaginer, par exemple, que définir la police sur un composant, nécessite de charger cette police dans une table interne à awt, et que si tu tripatouille cette table en même temps dans l'EDT et dans ton thread, ça va causer des soucis. A priori, ce n'est pas documenté donc non garantis. Remarque que si tu bidouille un truc visible en dehors de l'EDT, dans 99.99% des cas, ca ne posera pas de soucis. L'ennui, c'est que ça se posera de manière aléatoire.

    Non, le doinbackground ne s'exécute pas dans l'EDT, c'est sont but. Par contre, tu peux updater un status dans le doinbackground, et la parite edt ira chercher cet update et tu pourra l'intégrer dans swing. Genre tu lit le fichier xml de config dans le doinbackground, et au fur et à mesure que tu charge des éléments du xml, tu peux mettre à jour une liste des icones à charger (par l'edt).

  13. #13
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2011
    Messages
    442
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2011
    Messages : 442
    Points : 417
    Points
    417
    Par défaut
    Ca a l'air bien en théorie, mais j'ai un peu de mal à voir comment faire en pratique.

    Lors de l'initialisation des actions, je leur associe une icone SELECTED et un icone ROLLOVER. A ce moment là, je les charges. Plus tard, je crée les boutons à partir des actions. Comment je peux faire pour faire la même chose mais sans charger les images dans l'EDT ?

  14. #14
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Normalement, les icone sont déjà chargées de manière asynchrones par l'EDT.

    Quand tu fais un truc du genre

    bouton.setIcon(new ImageIcon(ressource));

    A la sortie, tout est associé, mais l'image n'est pas encore chargée. De manière asynchrone, elle le sera, les imageobserver seront notifier et le bouton se rafraichira

  15. #15
    Membre éclairé Avatar de JoeChip
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    536
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2008
    Messages : 536
    Points : 803
    Points
    803
    Par défaut
    la création des boutons avec le chargement de toutes les icônes
    Bizarre que ça prenne tant de temps, il y a combien de boutons ?
    Sans danger si utilisé conformément au mode d'emploi.

    (anciennement BenWillard, enfin moins anciennement que ... enfin bon c'est une longue histoire... Un genre de voyage dans le temps...)

  16. #16
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2011
    Messages
    442
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2011
    Messages : 442
    Points : 417
    Points
    417
    Par défaut
    Le problème, c'est que comme j'utilise des actions, je fais plutôt du

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    action.putValue(Action.LARGE_ICON_KEY, new ImageIcon("..."));
    Et ensuite j'applique les actions aux boutons.

    Est-ce que c'est encore asynchrone dans ce cas ?

    Mais sinon, je pense qu'il y a aussi les composants en eux-même qui prennent du temps à charger. Par exemple, un JTextPane avec un HTMLDocument et un HTMLEditorKit, ça me prend 1,5 secondes. C'est normal ?

  17. #17
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Je me suis avancé trop vite. ImageIcon est synchrone par défaut. Pour y aller de manière asynchrone, c'est assez simple:


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     Image image = Toolkit.getDefaultToolkit().getImage("...."); // chargement asynchrone
    action.putValue(Action.LARGE_ICON_KEY, new ImageIcon(image)); // ne tiens pas compte a priori de l'état de chargement

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Threads et synchronisation
    Par divxdede dans le forum Concurrence et multi-thread
    Réponses: 6
    Dernier message: 25/09/2007, 14h26
  2. Thread et synchronisation
    Par Invité dans le forum Concurrence et multi-thread
    Réponses: 8
    Dernier message: 15/03/2007, 11h17
  3. créer Thread et synchronisation C et VB
    Par storm_2000 dans le forum Général Dotnet
    Réponses: 1
    Dernier message: 20/01/2007, 12h49
  4. [THREAD] Problème synchronisation
    Par goddet dans le forum Débuter avec Java
    Réponses: 3
    Dernier message: 25/10/2006, 09h16
  5. [JNI] Class Thread et Synchronisation
    Par SteelBox dans le forum Entrée/Sortie
    Réponses: 3
    Dernier message: 22/02/2006, 23h40

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