:: Enseignements :: Master :: M1 :: 2011-2012 :: Java Avancé ::
![[LOGO]](http://igm.univ-mlv.fr/ens/resources/mlv.png) | Verrous et attente passive |
Exercice 1 - Producteur et consommateur
On souhaite écrire un programme permettant de simuler un
comportement de producteurs/consommateurs.
Un producteur est un thread qui à intervalle régulier va produire un message.
Un consommateur est un thread qui à intervalle régulier va lire un message,
puis afficher ce message.
-
Rappeler l'intérêt d'une architecture producteur/consommateur.
-
Écrire une méthode permettant d'afficher périodiquement un message.
-
Écrire une méthode créant le Runnable d'un producteur
avec en paramètre la chaîne de caractères qui sera produite par le producteur
et insérée dans une file (FIFO).
Pour implanter la file, utiliser une implémentation de la classe java.util.Queue<E> telle
java.util.LinkedList. N'oubliez pas de gérer la concurrence !
-
Faire la même chose avec un consommateur en prenant en paramètre un entier
unique id. Le consommateur, après avoir retiré un message de la file,
affichera celui-ci avec son numéro unique id.
-
On considère ci-après que les producteurs produisent deux fois plus vite que
les consommateurs ne consomment. Quels sont les éventuels problèmes de votre
implémentation?
Résoudre les problèmes sans changer le type de file.
-
On considère maintenant que la vitesse des producteurs et consommateurs n'est
pas fixée et que la file possède une taille maximale. Quels nouveaux problèmes
peuvent survenir?
Peut-on y remédier de façon efficace sans changer le type de file?
Exercice 2 - File bloquante synchronisée
On souhaite maintenant écrire notre propre classe de liste bloquante
appelée SynchronizedBlockingQueue, basée en interne
sur une ArrayDeque.
-
Écrire un constructeur prenant en paramètre la capacité
maximale de la file bloquante.
-
Écrire deux méthodes privées isFull et
isEmpty testant si la file est pleine ou vide.
-
Écrire les méthodes put et take
qui, respectivement, insère un message dans la file en bloquant si
la file est pleine, et enlève un message de
la file en bloquant si la file est vide.
Vous utiliserez la méthode Object.wait()
pour effectuer l'attente.
Attention aux risques de spurious wakeup
(la condition doit être systématiquement vérifiée à la sortie du wait) !
Pour réveiller les threads en attente, comparer les méthodes
Object.notify() et Object.notifyAll()
et indiquer celle qu'il vaut mieux utiliser ici.
-
Comment faire pour vérifier en mode debug que les méthodes isFull et
isEmpty sont bien appelées dans un contexte synchronisé ?
Exercice 3 - File bloquante verrouillée
On souhaite maintenant une autre implémentation de liste bloquante
appelée LockedBlockingQueue utilisant
les java.util.concurent.locks.Lock à la place des blocs synchronisés.
-
Comment peut-on créer une condition à partir d'un
Lock ?
-
Quel est l'intérêt d'utiliser des conditions plutôt que
des wait/notify ?
-
Comment faire pour vérifier en mode debug que les méthodes isFull et
isEmpty sont appelées entre les méthodes
lock et unlock ?
-
Écrire les méthodes put et take
de la classe LockedBlockingQueue.
© Université de Marne-la-Vallée