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][Synchronisation] Exclusion mutuelle [Infos]


Sujet :

Concurrence et multi-thread Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Juin 2003
    Messages : 28
    Par défaut [Thread][Synchronisation] Exclusion mutuelle
    Salut à tous, j'ai une ptite question :

    J'ai deux méthodes

    A()

    B()

    J'aimerai faire en sorte que deux treads ne puissent appeler les deux méthodes en même temps mais que deux threads puissent appeller les méthode A() ou (exclusif) b() en même temps.

    EX :

    Thread 1 : appelle A()
    Thread 2 : appelle A()

    OK


    Thread 1 : appelle B()
    Thread 2 : appelle B()
    Thread 3 : appelle B()

    OK


    Thread 1 : appelle B()
    Thread 2 : appelle A()

    PAS OK

    Vous voyez le truc...

    Merci

  2. #2
    Membre Expert Avatar de nuke_y
    Profil pro
    Indépendant en analyse de données
    Inscrit en
    Mai 2004
    Messages
    2 076
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Indépendant en analyse de données

    Informations forums :
    Inscription : Mai 2004
    Messages : 2 076
    Par défaut
    Donc en bref, B ne doit pas pouvoir être appelée tant que A est en cours d'exécution et pareil pour A.

    Et si tu gères des variables globales aInRun et bInRun ce qui donne :

    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
     
    public class MaClasse ... Thread...
    {
     boolean aInRun = false;
     boolean bInRun = false;
     
     public void a()
    {
     aInRun = true;
     ...
     
     aInRun=false;
    }
     
     public void b()
    {
     bInRun = true;
     ...
     
     bInRun=false;
    }
     
    public MaClasse()
    {
      .... 
      if (!aInRun) b(); // impossible de lancer b en même temps que a
      ...
      if (!nInRun) a(); // impossible de lancer a en même temps que b
      ...
      while(aInRun); // on attend la fin de a pour pouvoir lancer b
      b();
    }
    Et si tes threads ne partagent pas les infos (je suis pas très à l'aise avec les thread) met les2 variables globales en static.

  3. #3
    Membre éprouvé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    95
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 95
    Par défaut
    Mouay, il manque des synchronized déjà pour l'accès aux ressources communes. Ensuite, le while(aInRun);, il y a rien de pire pour gérer des threads, sauf si on veut pourrir les perfs du proc, c'est donc à bannir !! Il faut utiliser les méthodes wait() et notify() pour endormir et réveiller un Thread.

    Bon, pour revenir au problème, je dirai que l'idée des variables aInRun et bInRun est pas mal (à utiliser avec des getters "synchronized"), mais qu'il faudrait en plus réserver la ressource si possible, genre

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    public synchronized tryToAllocateA() {
      if (!bInRun) {
        aInRun = true;
        return true;
      } else {
        return false;
      }
    }
    Parceque si on sépare la réservation du test, on perd tout l'intéret du synchronized.

    Ensuite, quand on veut appeller A ou B, si la réservation n'est pas possible, on endors le processus. Ca donne donc quelquechose du genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    public void A() {
      while ( tryToAllocateA() ) {
        wait();
      }
      ...
      freeA();
      notifyAll();
    }
    Bon, je ne suis pas non plus un spécialiste des threads, mais ça devrait plutôt ressembler à ça je pense. Après, on peux améliorer, notament en gérant une liste fifo des threads selon leut demande de réservation, pour que ce soit plus équitable, et on remplacer les notifyAll() par un notify() sur le bon Thread.

  4. #4
    Membre Expert Avatar de nuke_y
    Profil pro
    Indépendant en analyse de données
    Inscrit en
    Mai 2004
    Messages
    2 076
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Indépendant en analyse de données

    Informations forums :
    Inscription : Mai 2004
    Messages : 2 076
    Par défaut
    Bah j'avais prévenu que j'étais pas à l'aise avec les threads...

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Juin 2003
    Messages : 28
    Par défaut
    Merci pour les réponses.


    Il s'agit là d'une bonne piste mais je me pose une question concernant la méthode freeA().

    Si j'ai 2 thread exécutant en ce moment même la méthode A, sachant qu'aucun thread n'exécute la méthode B.

    Le thread 1 va passer en premier dans freeA() et va mettre AInRun à false.
    (Le thread 2 est encore quelque part dans la méthode A...)

    Arrive alors un thread qui exécute la méthode B. Le flag AInRun étant à faux, il passe et exécute la méthode B.

    On se retrouve donc avec un tread exécutant A et un thread exécutant B...

    En fait, c'est la méthode free qui ferait foirer dans ce cas précis. Je me dis alors que les deux booleéns ne sont ptet pas suffisants..

    Qu'en pensez-vous ?

  6. #6
    Membre Expert Avatar de nuke_y
    Profil pro
    Indépendant en analyse de données
    Inscrit en
    Mai 2004
    Messages
    2 076
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Indépendant en analyse de données

    Informations forums :
    Inscription : Mai 2004
    Messages : 2 076
    Par défaut
    Mhmm chaque Thread devrait posséder ses propres booléen alors ...

  7. #7
    Membre éprouvé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    95
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 95
    Par défaut
    Tu as parfaitement raison. Tu peux dans ce cas utiliser un entier au lieu d'un booléen, pour compter le nombre de Thread qui exécute A (ou B).

  8. #8
    Membre Expert Avatar de nuke_y
    Profil pro
    Indépendant en analyse de données
    Inscrit en
    Mai 2004
    Messages
    2 076
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Indépendant en analyse de données

    Informations forums :
    Inscription : Mai 2004
    Messages : 2 076
    Par défaut
    Pas bête les entiers, incrémentation pour 1 thread de plus à True et décrementation pr 1 de moins. Avec test aInRun > 0.

    Sinon il faudrait ptet voir avec un espèce de pool de thread qui s'occupe de gérer en amont ce genre de chose. Il s'occupe de savoir si un de ses thread est dans une des 2 méthodes et renvoit le résultat.

  9. #9
    Membre éprouvé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    95
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 95
    Par défaut
    Mhmm chaque Thread devrait posséder ses propres booléen alors ...
    Non, je dirai plutôt que les ressources partagées doivent être centralisées dans une autre classe, sinon il faudrait demander à chaque thread ce qu'il exécute, et ça me semble assez difficile à gérer. Ca doit être un truc du genre

    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
    33
    34
    public class Ressource {
     
      private int nbThreadRunningA;
      private int nbThreadRunningB;
      private static Ressource instance = null;
     
      protected Ressource() {
        nbThreadRunningA = 0;
        nbThreadRunningB = 0;
      }
     
      public static Ressource getInstance() {
        if (instance  == null) {
          instance = new Ressource();
        }
        return instance;
      }
     
      public synchronized void tryToAllocateA() { 
        if (nbThreadRunningB  == 0) { 
          nbThreadRunningA++;
          return true; 
        } else { 
          return false; 
        } 
      }
     
      public synchronized void freeA() {
        nbThreadRunningA--;
      }
     
       ...
     
    }

    Ensuite, pour les autres threads, le principe reste le même.

Discussions similaires

  1. Thread exclusion mutuelle et pb de famine
    Par TiTiSeb dans le forum Concurrence et multi-thread
    Réponses: 5
    Dernier message: 25/11/2008, 02h33
  2. Utiliser un héritage avec exclusion mutuelle correctement
    Par akecoocoo dans le forum Décisions SGBD
    Réponses: 2
    Dernier message: 20/11/2005, 22h54
  3. Exclusion mutuelle
    Par Jahjouh dans le forum C++
    Réponses: 15
    Dernier message: 24/09/2005, 12h32
  4. Réponses: 1
    Dernier message: 23/05/2005, 15h52
  5. [Thread] synchronisation globale
    Par guejo dans le forum Concurrence et multi-thread
    Réponses: 6
    Dernier message: 16/02/2005, 11h56

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