:: Enseignements :: ESIPE :: E4INFO :: 2016-2017 :: Concurrence ::
![[LOGO]](http://igm.univ-mlv.fr/ens/resources/mlv.png) | Producteur / consommateur |
Exercice 1 - Producer / Consumer
Nous cherchons dans cet exercice à simuler un environement avec plusieurs producteurs et
plusieurs consommateurs.
Pour cela, nous utiliserons des threads qui exécuteront périodiquement soit un code qui
produit des valeurs soit un code qui consomme ces valeurs.
-
Rappeler quel problème résoud le design pattern Producer/Consumer et
comment il fonctionne ?
-
L'interface d'un buffer utilisé pour un producteur / consommateur est nommée
java.util.concurrent.BlockingQueue en Java.
Comment s'appellent les méthodes de l'interface BlockingQueue qui permettent, respectivement,
de mettre une valeur dans la queue et d'en retirer une valeur ?
-
Ecrire dans un main une thread qui affiche périodiquement (disons toutes les 1 ms)
le texte "hello" sur la console.
Modifier votre code pour avoir deux threads qui affichent périodiquement "hello 0" ou "hello 1"
(hello suivi d'un numéro de thread) respectivement toutes les 1 ms et toutes les 4 ms.
Note: pas de copier/coller SVP !
-
Modifier une nouvelle fois le code pour que, au lieu d'afficher les messages
sur la console, les deux threads les insèrent dans une BlockingQueue.
Que se passe t'il si l'implantation de BlockingQueue est une LinkedBlockingQueue ?
Même question si l'implantation est une ArrayBlockingQueue.
Que peut-on en conclure ?
-
Ecrire un nouveau code qui permet de retirer les messages de la BlockingQueue et de les
afficher sur la console. Créer 3 threads exécutant le code respectivement toutes les 2 ms, 3 ms
et 5 ms.
Faites varier le nombre de threads et les temps pour voir ce qu'il se passe.
Exercice 2 - Queue bloquante
Nous allons maintenant ré-implanter (en partie) une queue bloquante bornée utilisant un tableau circulaire
avec ses deux opérations put et take.
Note: la classe java.util.ArrayDeque implante déjà un buffer circulaire non thread-safe.
-
Ecrire une classe SynchronizedBlockingBuffer utilisant des blocs
synchronized qui dans un premier temps, lève une exception
-
dans put si il n'y plus de place (la queue est pleine).
-
dans take si il n'y a pas d'élement (la queue est vide).
et possède une taille (strictement positive) donnée à la construction.
Pour tester, vous pourrez ré-utiliser le code du premier exercice.
-
Modifiez votre code pour que la méthode put soit bloquante si
la queue est pleine.
Attention, penser à reveiller la thread lorsque la queue n'est plus pleine.
-
Modifiez votre code pour que la méthode take soit bloquante si
la queue est vide.
-
Ecrire une nouvelle classe LockedBlockingBuffer qui utilise les verrous
ré-entrant du package java.util.concurrent.locks.Lock.
© Université de Marne-la-Vallée