Examen 2h sur machine


L'examen est composé d'une partie écrite sur feuille de 45 maximum, à faire en premier et de deux exercices qui peuvent être traités dans l'ordre que vous voulez.

Rappel : vous devez configurer le workspace d'Eclipse (File > Switch WorkSpace) pour qu'il corresponde au répertoire EXAM présent dans le home de votre session de TP noté.

Vérifier que tous vos fichiers sont bien dans le répertoire EXAM. Tout ce qui n'est pas dans ce répertoire est perdu quand vous vous déconnectez.

Vous avez le droit de consulter les transparents du cours pendant tout l'examen.

QCM (sur papier)

Échange circulaire

Le but de cet exercice est de créer une classe thread-safe CyclicExchanger qui va permettre à n threads de se faire passer des valeurs.

Un CyclicExchanger<T> est créé avec un certain nombre de participants nbParticipants. Cette classe possède une seule méthode exchange(T value).

Quand un thread appelle exchange, il va attendre que nbParticipants threads aient appelé la méthode exchange avant de renvoyer la valeur fournie par l'un des autres threads (celui qui arrive après lui, sauf le dernier). Plus précisément, le i-ème thread qui a appellé exchange renverra la valeur donnée par le (i+1)-ème thread qui a appellé exchange, sauf pour le dernier thread qui renverra la valeur donnée par le premier thread.

Par exemple, si nbParticipants vaut 3 et que le premier thread appelle exchange avec 1, le second avec 2 et le troisième avec 3, alors la méthode exchange renverra 2 pour le premier thread, 3 pour le second thread et 1 pour le troisième thread.

Pour l'instant, si un thread appelle la méthode exchange après que nbParticipants threads aient appelé exchange, la méthode lèvera une IllegalStateException.

Écrire la classe thread-safe CyclicExchanger.

Dans la classe CyclicExchanger écrire une méthode main qui crée un objet CyclicExchanger pour 5 threads et qui démarre 5 threads. Le i-ème thread attend i secondes et appelle exchange avec la valeur i et affiche la valeur renvoyée par exchange.

Enchère

Dans cet exercice, on veut que 5 threads puissent proposer des entiers positifs comme enchères. Si un thread propose une valeur qui a déjà été proposée, sa valeur est ignorée. Dans ce cas, le thread est mis au courant et peut proposer une autre valeur. Lorsque tous les threads ont proposé une valeur, le thread qui a proposé la plus petite valeur peut changer sa valeur avec pour seule information la moyenne des valeurs proposées par tous les threads. Pendant ce temps, les autres threads sont bloqués et ne peuvent donc pas changer leur valeur. Le processus se répète avec le thread qui a maintenant proposé la plus petite valeur.

Par exemple, le thread 1 propose 1, le thread 2 propose 2, le thread 3 propose 3, le thread 4 propose 4. Le thread 5 propose 1, sa valeur est ignorée et le thread 5 le sait. Il propose 5. Le thread 1, qui a proposé la petite valeur, est débloqué et sait que la moyenne des valeurs proposées est 3 (i.e., (1+2+3+4+5)/5). Il propose 3, sa valeur est ignorée et il le sait. Il propose 9. Le thread 2 a maintenant proposé la plus petite valeur (2), il est débloqué et il sait que la moyenne des valeurs proposées est 5 (9+2+3+4+5)/5). Il peut proposer une nouvelle valeur ...

Plus précisément, on veut que le programme démarre 5 threads numérotés de 1 à 5. Le thread d'indice i va :

On s'attend à un affichage de ce genre :

Thread 5 proposes 5
Thread 1 proposes 1
Thread 4 proposes 4
Thread 2 proposes 2
Thread 3 proposes 3
Thread 1 was unblocked because its proposed value 1 is now the smallest
Thread 1 proposes 4
Thread 1 proposed value 4 was rejected
Thread 1 proposes 5
Thread 1 proposed value 5 was rejected
Thread 1 proposes 6
Thread 2 was unblocked because its proposed value 2 is now the smallest
Thread 2 proposes 5
Thread 2 proposed value 5 was rejected
Thread 2 proposes 6
Thread 2 proposed value 6 was rejected
Thread 2 proposes 7
Thread 3 was unblocked because its proposed value 3 is now the smallest
Thread 3 proposes 6
Thread 3 proposed value 6 was rejected
Thread 3 proposes 7
Thread 3 proposed value 7 was rejected
Thread 3 proposes 8
...

Écrire une classe thread-safe Bid et une classe Application dont la méthode main démarre les 5 threads décrits précédemment en utilisant votre classe thread-safe Bid.
Comme contrainte, on impose qu'il n'y ai aucune synchronisation dans le main et que les threads ne doivent pas pouvoir demander à Bid les valeurs proposées par les autres threads.