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

Concurrence et multi-thread Java Discussion :

Thread en attente d'événement


Sujet :

Concurrence et multi-thread Java

  1. #1
    Membre habitué
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2007
    Messages
    259
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2007
    Messages : 259
    Points : 128
    Points
    128
    Par défaut Thread en attente d'événement
    Quelle est ma meilleure façon pour mettre en place cette solution:
    J'ai mon application web qui relaie un appel client vers un backoffice. Le thread du client est en attente de la réponse
    du backoffice qui arrive par un autre canal sur l'application web.
    Dans un premier temps j'ai un mis un sleep sur le thread du client le temps que le backoffice réponde. Mais il arrive que
    le backoffice mette plus de temps à répondre.

  2. #2
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Salut,

    Le moyen le plus simple est d'utiliser un wait et un notify (sinon il y a les classes Lock/Condition, mais c'est plus complexe je trouve). Par ailleurs, si tu avais plusieurs réponses à recevoir, le CountDownLatch serait le plus simple (cela dit, tu pourrais l'utiliser également dans ton cas, en disant que tu n'attends qu'une seule tâche).
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  3. #3
    Membre habitué
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2007
    Messages
    259
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2007
    Messages : 259
    Points : 128
    Points
    128
    Par défaut
    Merci pour votre réponse.
    J'ai écrit le code ci-dessous(wait/notify).
    Qu'est ce que vous en pensez ?
    Les synchronized sur les méthodes sont indispensables?
    Le risque n'est pas que la méthode getMessage tombe dans une bouche infinie ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
     
    package fr.test;
     
    import java.util.HashMap;
    import java.util.Map;
     
    public class ProducerConsumer  {
     
        private Map<Integer, String> messages = new HashMap<Integer, String>();
     
     
     
        public synchronized void putMessage(int idMessage) throws InterruptedException {
            messages.put(idMessage, new java.util.Date().toString());
            System.out.println("put message : " + idMessage);
            notifyAll();
     
        }
     
     
        public synchronized String getMessage(int idMessage) throws InterruptedException {
            wait();
            String message = messages.get(idMessage);
            if (message == null) {
            	System.out.println("get message : null " );
                this.getMessage(idMessage); 
            }
            System.out.println("get message : " + idMessage + " date : " + message);
            return message;
        }
     
    }

  4. #4
    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
    mouais, il y a quand même des problèmes avec ton code.

    D'abord le problème de base: tu met en pause ton thread web HTTP. Tu ne devrais jamais faire ça, le moindre problème et c'est ton serveur web qui s'écroule.
    Ton code est extrèmement naif, il n'y a aucun lien entre l'id du message attendu par le thread qui fait le wait et l'id a a provoqué le notify.
    Un requête http ne devrait pas mettre du temps à répondre. Si le backen est lent, il faut procéder en deux étape: une requête http qui pousse la demande vers le back et 1 ou plusieurs requête http pour interroger l'état.

  5. #5
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par friedamichelle Voir le message
    Les synchronized sur les méthodes sont indispensables?
    C'est surtout sur un identifiant unique partagé entre le get et le put qu'il faudrait mettre le synchronized/wait et le synchronized/notify.

    Citation Envoyé par friedamichelle Voir le message
    Le risque n'est pas que la méthode getMessage tombe dans une bouche infinie ?
    Là, tu auras plutôt une stackoverflow. Et même si ça le faisait pas, tu as oublié de récupérer le message dans l'appel récursif, donc ta méthode retournera null systématiquement si le message n'est pas dans la map dès le début. Il ne faut pas faire d'appel récursif de toute manière, mais une boucle tant que le message n'a pas été trouvé dans la map.

    Et fait un wait avec timeout pour ne pas attendre un message qui n'arrivera jamais.
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  6. #6
    Membre habitué
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2007
    Messages
    259
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2007
    Messages : 259
    Points : 128
    Points
    128
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    mouais, il y a quand même des problèmes avec ton code.

    D'abord le problème de base: tu met en pause ton thread web HTTP. Tu ne devrais jamais faire ça, le moindre problème et c'est ton serveur web qui s'écroule.
    Ton code est extrèmement naif, il n'y a aucun lien entre l'id du message attendu par le thread qui fait le wait et l'id a a provoqué le notify.
    Un requête http ne devrait pas mettre du temps à répondre. Si le backen est lent, il faut procéder en deux étape: une requête http qui pousse la demande vers le back et 1 ou plusieurs requête http pour interroger l'état.
    Si je ne peux pas faire de wait, je fais quoi à la place ?
    Voila le scénario:
    - Le client envoie une requête au serveur qui la relaie au backend, le "thread client" attend la réponse du backend.
    - Le backend répond finalement au serveur (ajoute la réponse dans une map) et le "thread client" récupère la réponse (dans la map) et la retourne au client.


    Mon code est celui du serveur web. Le premier appel est le getMessage qui vient récupérer un message, et en ce moment là , le message n'est pas encore disponible d'où le wait.
    Ensuite, le backend fait l'appel putMessage et ajoute le message et notify le premier appel pour récupérer le message

  7. #7
    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
    Si ton backend répond en asynchrone, on peux supposer que c'est parce que c'est une opération lente; Le fait que faire un sleep qui est aussi une mauvaise idée foire car parfois c'est plus long et un bon signe. Il faut revoir ton scénario. Ton backend est asynchrone: répond en asynchrone au client ,ne fait pas de wait ,sleep ou autre. Ton thread http ne dois pas mettre plus de quelques centains de millisecondes à répondre dans le pire des cas. Si le browser attends une réponse pendant 3/4 secondes, tu peux être sur que ton utilisateur va cliquer 15 fois sur refresh et ton backend va se faire spammer la gueule.

    Pour résumer, le thread client ne dois pas "attendre" la réponse. Si tu fais un wait pour attendre qu'un autre thread fasse un notify, assure toi de limiter le wait à 50 ou 100ms.

  8. #8
    Membre habitué
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2007
    Messages
    259
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2007
    Messages : 259
    Points : 128
    Points
    128
    Par défaut
    Au final, l'implémentation du sleep a été déportée sur le client web. Cela a pour l'avantage de de faire tomber le serveur en cas de problème.
    Merci à tous.

Discussions similaires

  1. Réponses: 1
    Dernier message: 18/04/2008, 17h07
  2. [C#.NET 2] Thread "en attente"
    Par Ticoche dans le forum Windows Forms
    Réponses: 16
    Dernier message: 25/02/2008, 15h00
  3. mise en attente d'évènements
    Par BigNic dans le forum C#
    Réponses: 1
    Dernier message: 07/12/2007, 16h22
  4. tuer un thread en attente (socket)
    Par LesLemmings dans le forum Visual C++
    Réponses: 1
    Dernier message: 18/03/2007, 10h50
  5. [TECHNIQUE]Attention aux évènements statiques
    Par joujoukinder dans le forum Général Dotnet
    Réponses: 2
    Dernier message: 21/09/2006, 21h16

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