US

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.

1 
2 
3 
4 
5 
6 
7 
8 
 
9 
10 
11 
12 
13 
14 
15 
16 
17 
public class SharedIntBuffer
{
    private final int[] buffer = new int[20];
    private int first, last, size = 20, inBuffer;
 
    public synchronized int read()
    {
        // Si le buffer n'est pas vide, retourne l'élément suivant et le supprime du buffer
        // Sinon, bloque jusqu'à ce qu'un élément soit ajouté
    }
 
    public synchronized void put (int i)
    {
        // Si le buffer n'est pas plein, ajoute l'élément i dans le buffer
        // Sinon, bloque jusqu'à ce que de la place soit libérée
    }
}
Listing 3.10 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.

1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
public synchronized int read()
{
    while (inBuffer == 0)
    {
        try
        {
            wait();
        }
        catch (InterruptedException exception){}
    }
 
    first = (first + 1) % size;
    inBuffer--;
    notifyAll();
    return buffer[first];
}
Listing 3.11 Méthode 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.

1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
public synchronized void put (int i)
{
    while (inBuffer == size)
    {
        try
        {
            wait();
        }
        catch (InterruptedException exception){}
    }
 
    last = (last + 1) % size;
    inBuffer++;
    buffer[last] = i;
    notifyAll();
}
Listing 3.12 Méthode 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.

  • Espace membre
  • Learning Center
  • Les forums
  • Livre d'or
  • Imprimer
  • Boutique
  • Info
  • Règlement
  • Erreur
  • Newsletter

MyPagerank.Net

Firefox 3.6

Browse Happy logo

Open Clip Art Library

Join our Facebook Group

Twitter

Copyright © 2000-2012 UKO. Toute reproduction strictement interdite sans autorisation du webmaster

Valid XHTML 1.1 !
Valid CSS2 !
Level Triple-A conformance icon, W3C-WAI Web Content Accessibility Guidelines 1.0
ICRA Internet Content Rating Association
Creative Commons License
Site optimisé pour Firefox avec une résolution 1024x768 --- Page chargée en 0.0458241 secondes --- This site uses Thumbshots previews