TP 1 Partage de ressources entre threads 1. Producteur / Consommateur Pour illustrer les mécanismes de synchronisation entre threads, on se propose de développer une petite application producteur/consommateur : un thread producteur crée des messages (e.g. la date courante) et les place dans une file d'attente (e.g. un Vector). Un thread consommateur retire un message de la file d'attente et l'affiche. Pour rendre l'application plus réaliste on impose : que la file d'attente soit bornée. Lorsque la file d'attente est pleine le producteur se met en attente et lorsqu'elle est vide le consommateur se met en attente. que l'on puisse imposer un débit différent au producteur et au consommateur (chaque thread s'endormira (sleep) entre chaque itération) Ecrivez les classes Producteur et Consommateur. Ecrivez une classe Main qui permet de tester ces classes. Par exemple : public class Main { public static void main(String[] args) { Producteur p = new Producteur(5, 1000); p.start(); Consommateur c = new Consommateur(p, 2000); c.start(); } } Faites les modifications nécessaires pour que l'on puisse lancer plusieurs consommateurs simultanément. 2. Le dîner des philosophes Le dîner des philosophes est souvent utilisé pour illustrer les divers problèmes qui peuvent survenir lorsque plusieurs threads synchronisés accèdent de façon concurrente à un nombre limité de ressources. Cinq philosophes sont assis autour d'une table ronde. Ils passent leur temps à réfléchir et à manger. En face de chacun d'eux se trouve un bol de riz (en quantité infinie) et une baguette est placée entre chaque philosophe. Avant de pouvoir manger, chaque philosophe doit avoir pris successivement les baguettes qui se trouvent autour de lui. Les philosophes doivent trouver un moyen pour partager l'accès aux baguettes afin que chacun d'entre eux puisse successivement réfléchir et manger à l'infini. Faites une modélisation objet du problème et matérialisez le comportement des philosophes avec des threads. Le temps pris par chacune des opérations (réflexion, prise de baguettes, repas, pose de baguettes) sera simulé par un endormissement variable du thread. Assurez-vous que votre programme évite les interblocages. 3. Un tri multi-thread Implementez l'algorithme de tri suivant (t représente le tableau à trier) : Soient i et j (i <= j) les indices de l'intervalle de t à trier Si (j-i < 2) et (t[i] > t[j]), échanger t[i] et t[j] Sinon Soit k = i + (j - i)/2 Faire appliquer par un nouveau thread l'algorithme sur [i,k] Faire appliquer par un nouveau thread l'algorithme sur [k+1,j] Attendre la fin des 2 threads Faire une fusion triée des tris des 2 threads Informer le thread parent que le tri sur [i,j] est terminé