Vous êtes sur la page 1sur 7

1 2 Thread 3Partage de ressources entre threads :

TD1 Thread 1. Producteur / Consommateur

4 5Pour illustrer les mcanismes de synchronisation entre threads, on se propose de dvelopper 6une petite application producteur/consommateur : un thread producteur cre des messages 7(e.g. la date courante) et les place dans une file d'attente (e.g. un Vector). Un thread 8consommateur retire un message de la file d'attente et l'affiche. Pour rendre l'application plus 9raliste on impose : 10 que la file d'attente soit borne. Lorsque la file d'attente est pleine le producteur se met 11 en attente et lorsqu'elle est vide le consommateur se met en attente. 12 que l'on puisse imposer un dbit diffrent au producteur et au consommateur (chaque 13 thread s'endormira (sleep) entre chaque itration) 14 15
16 17 18 19 20 21 22 23

1.1. 1.2.

Ecrivez les classes Producteur et Consommateur. Ecrivez une classe Main qui permet de tester ces classes. Par exemple :
public class Main { public static void main(String[] args) { Producteur p = new Producteur(5, 1000); p.start(); Consommateur c = new Consommateur(p, 2000); c.start(); } }

24Faites les modifications ncessaires pour que l'on puisse lancer plusieurs consommateurs 25simultanment. 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41Un smaphore est un moyen pour garantir un accs limit une ressource. Ce smaphore 42modlis par une classe Semaphore possde un attribut entier limite dsignant le nombre 43d'accs simultan possible une ressource. Cette classe contiendra les mthodes acceder et 44liberer. La premire mthode sera autorise par un certain nombre de threads puis bloquera

2.

Synchronisation multithreads

1140515805.doc

45lorsque le nombre de threads aura atteint la limite. La deuxime mthode librera un accs 46la ressource. 47Afin de tester cette classe crer une classe Calculateur qui reprsente une machine disposant 48d'un certain nombre de processeurs. Elle possde une mthode unique calcul qui est bloquante 49lorsqu'il n'y a plus de processeur disponible. 50On a n threads (classe Personne) reprsentant des personnes employant le calculateur par la 51mthode calcul. Simuler l'usage d'un calculateur avec 5 processeurs par 10 personnes. 52 53Remarque : Lorsque vous crez la classe Personne par hritage de la classe Thread, vous 54 pouvez invoquer le constructeur parent donnant un nom votre Thread par 55 super(nom) et la mthode Thread.currentThread.getName permet de 56 rcuprer ce nom par exemple dans la mthode calcul vous pourrez ainsi 57 afficher quel thread appelle cette mthode. 58 59 60

2140515805.doc

61 62

Correction Producteur / Consommateur :

63Classe Producteur
64package prodcons; 65 66import java.util.Vector; 67import java.util.Date; 68 69public class Producteur implements Runnable { 70 71 private Thread thread; 72 private Vector queue; 73 private int Taillemax; 74 private long DureeAttente; 75 private boolean verbose; 76 77 /** 78 * Crer un nouveau Producteur 79 * 80 * @param Taillemax taille de la file d'attente 81 * @param DureeAttente temps d'attente entre chaque itration 82 */ 83 public Producteur(int Taillemax, long DureeAttente, boolean verbose) { 84 this.Taillemax = Taillemax; 85 this.DureeAttente = DureeAttente; 86 this.queue = new Vector(); 87 this.verbose = verbose; 88 thread = new Thread(this); 89 } 90 91 /** 92 * Dmarre le thread 93 */ 94 public void start() { 95 System.out.println("Producteur dmarr : taille file : " + Taillemax); 96 thread.start(); 97 } 98 99 /** 100 * Corps du thread 101 */ 102 public void run() { 103 try { 104 while(true) { 105 putMessage(); 106 Thread.sleep(DureeAttente); 107 } 108 } 109 catch(InterruptedException e) {} 110 } 111 112 /** 113 * Ajout d'un nouveau message dans la file 114 */ 115 private synchronized void putMessage() throws InterruptedException { 116 if (verbose) System.out.println("Producteur: ajout d'un nouveau 117message");

3140515805.doc

118 // Si file pleine, attendre 119 while(queue.size() >= Taillemax) { 120 wait(); 121 } 122 123 // Ajout d'un nouveau message 124 queue.addElement(new Date().toString()); 125 126 if (verbose) System.out.println("Producteur: message ajout (taille 127file = " + queue.size() + ")"); 128 129 // Notifier l'ajout d'un nouveau message 130 notifyAll(); 131 } 132 /** 133 * Supprime et retourne le premier message de la file 134 * 135 * @retourne le message 136 */ 137 public synchronized String getMessage() throws InterruptedException { 138 139 if (verbose) System.out.println("Producteur: retourne un message"); 140 // Si file d'attente vide, attendre 141 while(queue.size() == 0) { 142 wait(); 143 } 144 // premier message retourn 145 String message = (String)queue.firstElement(); 146 queue.removeElement(message); 147 148 if (verbose) System.out.println("Producteur: message retourn"); 149 // Notifier message donn 150 notify(); 151 return message; 152 } 153}

154Classe Consommateur
155package prodcons; 156 157public class Consommateur implements Runnable { 158 159 private Thread thread; 160 private String nom; 161 private Producteur prod; 162 private long DureeAttente; 163 164 /** 165 * Creer un nouveau Consommateur 166 * 167 * @param nom le nom du consommateur 168 * @param prod le thread producteur 169 * @param DureeAttente temps d'attente entre chaque itration 170 */ 171 public Consommateur(String nom, Producteur prod, long DureeAttente) { 172 this.nom = nom; 173 this.prod = prod; 174 this.DureeAttente = DureeAttente; 175 176 thread = new Thread(this);

4140515805.doc

177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200} 201 202 203 204

} /** * Dmarrage du thread */ public void start() { System.out.println("Consommateur " + nom + " dmarr"); thread.start(); } /** * Corps du Thread */ public void run() { try { while(true) { System.out.println(nom + ": " + prod.getMessage()); Thread.sleep(DureeAttente); } } catch(InterruptedException e) {} }

2051.3 Avec plusieurs Consommateurs :


206package prodcons; 207 208public class Main { 209 public static void main(String[] args) { 210 Producer p = new Producer(5, 1000, true); 211 p.start(); 212 213 Consumer c1 = new Consumer("LENT", p, 4000); 214 Consumer c2 = new Consumer("RAPIDE", p, 2000); 215 216 c1.start(); 217 c2.start(); 218 } 219}

220

5140515805.doc

221

Correction Synchronisation multithreads :

222 223package mltthrds; 1 2public class Semaphore { 3 private int limite; 4 5 public Semaphore(int limite) { 6 this.limite = limite; 7 } 8 9 public synchronized void acceder() { 10 if ( limite == 0) { 11 try { 12 wait(); 13 } catch (InterruptedException e) { } 14 } 15 limite--; 16 } 17 18 public synchronized void liberer() { 19 limite++; 20 notify(); 21 } 22} 23 24 25public class Personne extends Thread { 26 27 private Calculateur cal; 28 29 public Personne(String nom, Calculateur cal) { 30 super(nom); 31 this.cal = cal; 32 } 33 34 public void run() { 35 try { 36 Thread.sleep(1000 + (long)(Math.random() * 1000)); 37 cal.calcul(); 38 } catch (InterruptedException e){} 39 } 40} 41 42public class Calculateur { 43 Semaphore sem = null; 44 45 public Calculateur(int processeur) { 46 sem = new Semaphore(processeur); 47 } 48 49 public void calcul() { 50 sem.acceder(); 51 System.out.println("Calcul fait par personne " + 52Thread.currentThread().getName()); 53 try { 54 Thread.sleep(1000); 55 } catch(InterruptedException e) {} 56 sem.liberer(); 57 }

6140515805.doc

58 59 public static void main(String[] args) { 60 Calculateur c = new Calculateur(5); 61 for(int i = 0; i<10; i++) 62 { 63 Personne p = new Personne(""+ (i + 1 ), c); 64 p.start(); 65 } 66 } 67} 68 69

7140515805.doc