+ Synchroniser « à la source » pour le problème de compte en banque                  

Synchroniser « à la source » pour le problème de compte en banque

     

Le code est quasiment identique au code non synchronisé que vous avez peut-être déjà observé sauf que, avant de faire une opération bancaire sur le compte (ici, ces opérations sont représentées par la méthode credite), il faut obtenir un verrou sur le compte.

Un verrou peut être mis sur un objet :

Voir le cours ici sur l'introduction à la synchronisation.

Ici, la méthode credite est affectée du modificateur synchronized, cela implique que lorsque cette méthode est invoquée :

Le thread principal (qui exécute la méthode main) construit le premier banquier et fait démarrer le thread du premier banquier ; celui-ci pose un verrou sur le compte, entâme la méthode credite, laisse son tour à par la méthode yield au thread principal qui construit le second banquier et fait démarrer le thread du second banquier ; après avoir écrit son annonce d'embauche, le second banquier tente d'exécuter sa méthode credite mais se heurte au verrou mis sur le compte ; il se met en attente du compte et le premier banquier termine son travail avant que le second banquier fasse l'opération de crédit.

Voici le code et ce qu'on obtient :

class CompteSynchro
{
  int capital=0;

  synchronized void credite(Banquier1 leBanquier, int deCombien)
    {
      int montant;

      System.out.println(leBanquier.nom + " commence son travail");
      montant = capital;
      leBanquier.yield();
      System.out.println(leBanquier.nom+" continue son travail");
      capital = montant + deCombien;
    }
}

class Banquier1 extends Thread
{
  CompteSynchro unCompte;
  String nom;
  Banquier1(CompteSynchro unCompte, String nom)
    {
      this.unCompte = unCompte;
      this.nom = nom;
    }

  public void run()
    {
      System.out.println(nom + " est embauche");
      unCompte.credite(this,1);
    }
}

class EssaiBanquier1 
{
  public static void main(String[]Argv)
    {
      CompteSynchro unCompte = new CompteSynchro();
      Banquier1 Jean, Jacques;

      (Jean = new Banquier1(unCompte, "Jean")).start();
      (Jacques = new Banquier1(unCompte, "jacques")).start();
      try
	{
	  Jean.join();
	  Jacques.join();
	}
      catch(InterruptedException e){}
      System.out.println("Votre capital est de " + unCompte.capital);
    }
}
On obtient :
Jean est embauche
Jean commence son travail
Jacques est embauche
Jean continue son travail
Jacques commence son travail
Jacques continue son travail
Votre capital est de 2

Ici, vous pouvez répérer le programme.



© Irène Charon, Télécom ParisTech 2011