Buffer partagé
Maintenant qu'on a vu le mécanisme de wait / notify, on va l'appliquer sur un exemple concret. Ce qu'on veut faire, c'est implémenter un buffer partagé, avec un plafond sur le nombre d'éléments qu'il est possible de stocker dans le buffer. On veut pouvoir faire deux opérations : lire l'élément suivant et ajouter un élément, sachant que le buffer doit correspondre à une file.
De plus, le buffer doit pouvoir être utilisé de manière concurrente, c'est-à-dire par plusieurs threads en même temps. Le listing suivant vous montre le squelette de la classe.
|
|
SharedIntBuffer.Comme vous pouvez le lire dans les commentaires, il y a une particularité à ce buffer. La méthode read doit bloquer si le buffer est vide, et la méthode put doit bloquer lorsque le buffer est plein.
La méthode read
Voyons comment on peut implémenter la méthode read. Pour rappel, la méthode doit bloquer si la liste est vide. Sinon, il faut retirer l'élément suivant du buffer et le renvoyer.
|
|
read de la classe SharedIntBuffer.La première partie de la méthode permet de gérer le blocage qui doit être fait tant que le buffer est vide. Tant que le buffer est vide, on va endormir tous les threads qui tentent d'exécuter cette méthode, et va les ajouter à la liste d'attente de cet objet. Notez que comme la méthode est synchronized, le thread appelant aura déjà le lock sur l'objet courant et pourra donc appeler la méthode wait.
Notez que lorsqu'un thread endormi se réveillera, il ne passera pas immédiatement à la suite de la méthode. On va avant tout revérifier la condition (grâce à la boucle while). Ceci pour deux raisons : tout d'abord pour pallier les appels spontanés à notify exécutés par la JVM, et également pour gérer tous les réveils faits par notifyAll.
Ensuite, des lignes 12 à 15, on va lire l'élément suivant du buffer et le renvoyer. À la ligne 14, on fait appel à notifyAll. Cet appel permet notamment de réveiller les threads qui étaient en attente sur put car le buffer était plein.
La méthode put
Voyons maintenant la méthode put qui permet d'ajouter un élément au buffer. Pour rappel, cette méthode doit bloquer si le buffer est plein. Sinon, il suffit d'ajouter l'élément dans le buffer.
|
|
put de la classe SharedIntBuffer.La première partie de la méthode est tout à fait similaire à celle de la méthode read. Tant que le buffer est plein, il faut mettre les threads qui appellent cette méthode en attente sur l'objet courant.
Ensuite, dans la seconde partie de la méthode, on ajoute l'élément dans le buffer. Enfin, on termine par un appel à notifyAll pour réveiller tous les threads en attente, notamment ceux qui étaient bloqués parce que le buffer était vide.





















