Programmation Orientée Objet et Réseau en Java

TD 5


Nous abordons ici les exécutions concurrentes en Java, avec la notion de thread (processus léger) et les notions de synchronisation afférentes aux exécutions de portions de code concurentes.


Exercice 1 - Exécutions concurrentes

Écrire une classe Affiche1 qui étend la classe Thread. Cette classe possède comme champ un entier identifiant chaque instance. Elle redéfinit la méthode run() de la classe Thread pour qu'elle affiche, dans une boucle de longueur n fixée, un message indiquant le numéro de l'instance courante et l'indice de la boucle.

Écrire un programme qui crée deux instances de la classe Affiche1 et qui les démarre, après quoi il affiche dans une boucle de longueur n un message indiquant ``Processus léger initial'' suivi de l'indice de la boucle.

Écrire une classe Affiche2 fournissant les mêmes fonctionnalités que Affiche1 mais sans hériter de Thread. Tester cette classe dans le main précédement écrit.

Exercice 2 - Problèmes d'exclusion mutuelle

Écrire une classe Point avec deux champs entiers x et y, une méthode void moveTo(int x, int y) (qui déplace le point aux coordonnées passées en argument) et une méthode toString() qui affiche ce point au format (x,y).

Écrire une classe Init destinée à être exécutée dans un processus léger (Thread), c'est-à-dire implantant l'interface Runnable. Cette classe Init contient un constructeur à deux arguments Init(Point p, int val). Sa méthode run() déplace p en (val,val), puis affiche le point, et ce dans une boucle infinie.

Créer deux processus légers ayant pour cible (code à exécuter) deux objets de la classe Init construits avec le même point p et des valeurs différentes (par exemple, Init(p,1) pour l'un et Init(p,2) pour l'autre).

Démarrer les deux processus légers. Quels sont les différents affichages possibles pour le point? Que faire?

Exercice 3 - Producteur et consommateur

On désire développer une petite application simulant les comportements concurrents d'un ensemble de producteurs et de consommateurs de messages. D'un côté, les producteurs produisent des messages qu'ils stockent dans un buffer commun; de l'autre, les consommateurs récupèrent dans ce même buffer les messages (dans l'ordre où ils y ont été placés).

On doit respecter un certain nombre de contraintes et pouvoir paramétrer l'application:

  1. un producteur ne peut produire un message que si le buffer n'est pas plein et, bien sûr, un consommateur ne peut lire un message que si le buffer n'est pas vide;
  2. le débit de chaque producteur et de chaque consommateur est paramétrable à sa construction (il représente le temps d'attente entre deux productions ou deux consommations).

Écrire les classes Producteur et Consommateur permettant de mettre en oeuvre ces spécifications. On pourra implanter le buffer avec un ArrayList et chaque message produit doit être aisément identifiable. Chaque producteur et consommateur sera exécuté par un processus léger (Thread) différent, en concurrence avec les autres.

Exercice 4 - Un tri multi-thread

Soit t un tableau à trier. Implanter l'algorithme de tri suivant:

  1. Soient i et j (i<=j) les indices de l'intervalle de t à trier.
  2. Si (j-i < 2) et (t[i] > t[j]), échanger t[i] et t[j].
  3. Sinon:


Nicolas.Bedon[at]univ-mlv.fr - Etienne.Duris[at]univ-mlv.fr - Rémi.Forax[at]univ-mlv.fr - © Université de Marne-La-Vallée - Novembre 2001