TP2 : Threads Java


Téléchargez cette archive contenant des exemples et des squelettes de programme qu'il faudra compléter par la suite.



Exercice 0


Placez-vous dans le répertoire 'ExemplesDuCours'.
  1. Lancez le programme ExempleConcurrent plusieurs de fois de suite. Constatez que le résultat n'est pas toujours identique. Comprendre pourquoi.
  2. Lancez le programme EvtGenerator plusieurs de fois de suite. Comprendre les appels à wait() et notifyall() réalisés dans le code.



Exercice 1


Rendez-vous dans le répertoire 'ProdCons'.

Il y a dans ce système deux types de threads : Tous les threads communiquent par l'intermédiaire d'un entrepôt global, de taille fixée, initialement vide. Le problème consiste à synchroniser tous les threads en jeu, de façon à ce que les contraintes suivantes soient vérifiées :

  1. Completez le squelette de programme ProdCons.java pour qu'il ait les fonctionnalités décrites ci-dessus.

Rappels :



Exercice 2


Placez-vous dans le répertoire 'LecteurEcrivain'.

On se place ici dans le cadre d'un système disposant d'une donnée partagée et comportant deux types de threads : Le problème de synchronisation est ici défini par les contraintes suivantes :

Tel qu'il est défini, ce système peut se trouver dans une situation dite "de famine". En effet, imaginons qu'il y ait beaucoup de threads lecteurs, à un point tel qu'il y ait à tout moment au moins un thread lecteur utilisant la donnée partagée. Dans ce cas, un éventuel thread écrivain n'aura jamais accès à la donnée : il sera en situation de famine.

(Notez que dans certains cas particuliers la situation est symétrique. Si il y a "beaucoup" d'écrivains, les lecteurs risquent de rester à l'état de famine. Toutefois, si l'attribution des accès est équitable, cela ne devrait pas arriver.)

Nous allons ici choisir de régler ce problème en énoncant une règle de priorité :
Pour comprendre l'influence de cette règle, examinons un exemple impliquant 3 threads, deux lecteurs L1 et L2 et un écrivain E1, dans la séquence suivante :
Dans ce cas, la règle de priorité modifie le comportement global. En effet :
(Tout ceci suppose qu'il n'y a pas d'autre demande d'accès entre temps.)

  1. Completez le squelette de programme LecteurEcrivain.java pour qu'il ait les fonctionnalités décrites ci-dessus.
  2. Imaginez une autre stratégie pour qu'il n'y ait plus de situation de famine. Dans le système que vous proposez, un lecteur/écrivain devra attendre uniquement les lecteurs/écrivains arrivés avant lui. Il vous faudra donc gérer une file d'attente.



Exercice 3


Placez-vous dans le répertoire 'Tri'.

  1. Parallelisez l'algorithme de Tri du fichier Tri.java en utilisant les threads. Avec des mesures de temps (utilisez par exemple la méthode long System.currentTimeMillis() qui renvoie le nombre de millisecondes écoulées depuis le 01/01/1970) sur une grande liste d'entiers (prévoyez un générateur automatique).
  2. Vous montrerez que votre solution est efficace sur une machine multiprocesseur : actuellement, la machine 'codd' possède 4 processeurs et 'turing' en à 16.









[Page réalisée à à l'aide d'un document de Guillaume Latu]