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 :

Quelques questions sur la synchro de threads


Sujet :

Concurrence et multi-thread Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Inscrit en
    Juin 2006
    Messages
    570
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 570
    Par défaut Quelques questions sur la synchro de threads
    Bonjour, voila j'utilise depuis trop longtemps les threads sans vraiment connaitre les mécanismes, je voudrais donc clarifier certaine chose.

    Tout d'abord, le bloc synchronized.
    J'ai le code suivant :

    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
     
    int i;
    int j;
     
    public void a() {
       synchronized(this) {
       i++;
       }
       j++;
    }
     
    public void b() {
       synchronized(this) {
       j++
       i++;
       }
    }
    En effectuant ceci, cela veut bien dire que si un thread T1 appelle la méthode la méthode b, alors un thread T2 ne pourra pas réaliser le bloc synchronized de la méthode a (ou b) tant que le bloc synchronized appelé par T1 n'est pas terminé. Exacte ?

    Maintenant, si c'était la méthode a qui a était appelée par T1, vu que le bloc synchronized ne comprend pas l'instruction "j++", est ce que T2 peut commencer le bloc synchronized de la méthode b pour faire l'instruction j++ ?

    Ensuite, quand on fait synchronised (xxx). xxx correspond au mutex. Mais au final, je ne comprend pas réellement ce que cela fait.

    Enfin, questions sur wait et notify :
    Si je fais un wait sur un thread cela va l'endormir, mais que ce passe il si je fais un wait sur un objet ? Cela va "endormir" tous les threads qui utilisent cet objet ? (et je suppose que la réponse sera la mêem pour le notify)

    J'ai cru comprendre que si je faisais un wait sur un objet, rien ne m'assure qu'il ne va pas être réveillé par le scheduler sans que je ne fasse un notify. Est ce exacte ?

    Pourquoi est ce que si je fais un this.wait, ou même un obj.wait, j'aurais un illegaleMonitorStateException si je n'encapsule pas le tout dans un bloc synchonized ?

    Voila, comme vous pouvez voir, il y' a pas mal de chose que je ne maitrise pas bien ^^

  2. #2
    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 Djobird Voir le message
    En effectuant ceci, cela veut bien dire que si un thread T1 appelle la méthode la méthode b, alors un thread T2 ne pourra pas réaliser le bloc synchronized de la méthode a (ou b) tant que le bloc synchronized appelé par T1 n'est pas terminé. Exacte ?
    Exact !

    Citation Envoyé par Djobird Voir le message
    Maintenant, si c'était la méthode a qui a était appelée par T1, vu que le bloc synchronized ne comprend pas l'instruction "j++", est ce que T2 peut commencer le bloc synchronized de la méthode b pour faire l'instruction j++ ?
    Je ne suis pas sûr d'avoir compris... mais dès qu'un thread sors d'un bloc synchronized, tous les autres threads qui était bloqué sur un bloc synchronized peuvent y entrer.

    Citation Envoyé par Djobird Voir le message
    Ensuite, quand on fait synchronised (xxx). xxx correspond au mutex. Mais au final, je ne comprend pas réellement ce que cela fait.
    C'est la référence de l'objet qui servira de verrou.

    Avant d'entrer dans un bloc synchronized, le thread doit acquérir le verrou associé à l'objet. Tous les autres threads qui arriveront par la suite seront dans l'impossibilité de récupérer ce verrou et se mettront donc en sommeil.

    Lorsque le thread quitte le bloc synchronized, il libère ce verrou et envoi un signal qui réveille tous les threads en attente sur ce verrou. Ces derniers vont donc tenter de l'acquérir à nouveau pour entrer dans le bloc synchronized (s'il y a plusieurs threads en attente, un seul pourra prendre le verrou et les autres devront encore attendre).


    Bien sûr cela s'applique au verrou d'un même objet


    Citation Envoyé par Djobird Voir le message
    Enfin, questions sur wait et notify :
    Si je fais un wait sur un thread cela va l'endormir, mais que ce passe il si je fais un wait sur un objet ? Cela va "endormir" tous les threads qui utilisent cet objet ? (et je suppose que la réponse sera la mêem pour le notify)
    Non... mais je te l'accorde l'API de wait/notify n'est pas très clair et pas très bien placé (cela n'aurait jamais du faire partie de la classe Object !)

    En fait le wait() va libérer le verrou du bloc synchronized avant d'endormir le thread courant Les autres threads pourront alors acquérir le même verrou :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    synchronized(o) {
        // le thread possède le verrou sur 'o'
     
        o.wait(); // pendant le wait(), le thread libère le verrou sur 'o'
     
        // le thread possède de nouveau le verrou
    }
    Bien sûr avant de ressortir du wait(), le thread devra attendre de pouvoir récupérer à nouveau le verrou (si d'autre thread l'on pris entre temps).


    Citation Envoyé par Djobird Voir le message
    J'ai cru comprendre que si je faisais un wait sur un objet, rien ne m'assure qu'il ne va pas être réveillé par le scheduler sans que je ne fasse un notify. Est ce exacte ?
    Oui (même si en pratique cela peut être très rare).
    Il suffit d'utiliser une boucle conditionnel pour éviter cela :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    while ( jedoisdormir ) o.wait();
    Citation Envoyé par Djobird Voir le message
    Pourquoi est ce que si je fais un this.wait, ou même un obj.wait, j'aurais un illegaleMonitorStateException si je n'encapsule pas le tout dans un bloc synchonized ?
    Tout simplement parce que tu ne peux pas libérer le verrou du bloc synchronized (puisque tu ne le possède pas).



    a++

Discussions similaires

  1. Quelques question sur les threads
    Par Zoners dans le forum Concurrence et multi-thread
    Réponses: 8
    Dernier message: 15/04/2010, 22h19
  2. Quelques questions sur les threads
    Par benj63 dans le forum C++Builder
    Réponses: 28
    Dernier message: 21/11/2005, 13h27
  3. question sur le comportement des threads
    Par rose-bonbon dans le forum CORBA
    Réponses: 4
    Dernier message: 27/10/2004, 18h00
  4. Quelques question sur Win 32 Appli
    Par lvdnono dans le forum Windows
    Réponses: 5
    Dernier message: 15/06/2004, 12h37
  5. Quelques questions sur le TWebBrowser...
    Par CorO dans le forum Web & réseau
    Réponses: 3
    Dernier message: 17/01/2003, 21h23

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