:: Enseignements :: ESIPE :: E4INFO :: 2013-2014 :: Java Réseau I - Concurrence et E/S ::
![[LOGO]](http://igm.univ-mlv.fr/ens/resources/mlv.png) | TP noté de Concurrence |
Le but de ce TP noté est d'écrire quelques classes permettant
de vérifier que vous maitrisez les bases des mécanismes de protection
de code exécuté de manière concurrente.
Vos sources Java produites pendant le TP devront être placées sous le répertoire
EXAM de votre compte ($HOME) (qui est vierge dans l'environnement de TP noté);
sinon, elles ne seront pas récupérées.
Vous devez aussi configurer votre Eclipse (eclipse-lambda) pour utiliser la version
8 du JRE (qui est disponible ici /usr/local/apps/java8) et le compilateur
pour qu'il utilise la version 1.8.
Tout document papier autre que ce que vous avez imprimé vous-même est proscrit.
Vous pouvez consulter la javadoc à travers eclipse ou en lançant la commande
jdoc dans un shell.
Les seuls documents électroniques autorisés sont les supports de cours à l'url
http://igm.univ-mlv.fr/~forax/ens/java-avance/cours/pdf/.
Les exercices 1. et 2. sont complètement indépendants et peuvent être traités
dans n'importe quel ordre.
Exercice 1 - Liste à ajout en tête avec conservation du minimum
Considérons la classe
ListMin suivante, représentant une liste d'entiers qui doit
permettre, outre la création d'une liste contenant un entier, d'ajouter un élément en tête
de liste et de récupérer le plus petit élément de la Liste.
Actuellement, cette classe n'est pas thread-safe.
-
Dans un premier temps, sans se préoccuper de la gestion du maillon contenant la valeur
minimum (minNode),
modifiez le code pour qu'il soit thread-safe lors de l'ajout des éléments par
addFirst() en utilisant les opérations atomiques (sans utiliser de
synchronized ni de Lock si vous préférez).
-
Modifiez ensuite le code de sorte que la modification du maillon contenant la valeur
minimum (minNode) soit également thread-safe lors de l'ajout des éléments,
toujours en utilisant exclusivement des opérations atomiques.
On ne cherchera pas à essayer de garantir la cohérence entre l'état de la liste et
la valeur du minimum à tout instant, mais plutôt à éviter qu'un maillon ne soit pas pris
en compte dans la mise à jour du minimum,
i.e., après que toutes les threads aient fini leur travail, le minimum doit effectivement
renvoyer la plus petite des valeurs de la liste).
Exercice 2 - Enchères
Le but est d'implanter une classe
Auction qui permet de simuler un mécanisme
d'enchère. Pour simplifier le problème, une instance de la classe ne pourra gérer
qu'une seule enchère; si l'on veut simuler plusieurs enchères consécutives,
il faudra créer autant d'objets
Auction que d'enchères.
L'idée est que la classe possède deux méthodes
auction() et
bid(). La méthode
auction() prend en paramètre un nombre de millisecondes
et attend pendant le temps spécifié. La méthode
bid() permet à une thread qui l'exécute
de participer à l'enchère en cours (cette méthode peut être appelée par plusieurs
threads différentes). Elle est appelée avec un argument qui
représente une valeur de pari (ou d'enchère): la thread qui l'exécute est alors bloquée. Lorsque le temps spécifié par
l'appel à
auction() est terminé, l'ensemble des threads qui sont bloquées par un appel à
bid()) sur cette enchère sont libérées, et la plus grande des valeurs de pari soumises est
renvoyée par les méthodes
bid()).
public class Auction {
public void auction(int duration) throws InterruptedException {
//TODO
}
public int bid(int value) throws InterruptedException {
if (value < 0) {
throw new IllegalArgumentException("value < 0");
}
//TODO
}
}
-
Implanter les méthodes auction() et bid(), sachant
que si une thread en attente sur une des deux méthodes
est interrompue, alors une InterruptedException
devra être levée par la méthode.
Un main de test est disponible ici:
-
La façon dont InterruptedException est gérée n'est pas satifaisante car
-
Si la thread qui a appelée auction() est interrompue, les threads en
attente sur bid() attendent indéfiniment.
-
Si une thread qui a appelé bid() a la meilleure enchère et est
interrompue, à la fin de l'enchère, toutes les threads restantes vont penser
qu'une autre thread a gagné, alors que celle-ci n'est plus en attente sur bid().
Pour résoudre ces deux problèmes, l'idée est que dès qu'une des threads est interrompue,
qu'elle soit sur auction() ou sur bid(), alors toutes les threads qui
participent à l'enchère doivent lever l'exception InterruptedException.
Recopiez le code dans la classe Auction2 et faites les modifications nécessaires
pour implanter ce comportement.
Un main de test est disponible ici:
-
Pour finir, on veut faire en sorte qu'une seule thread soit capable d'appeler auction().
Lorsque la méthode auction() a été appelée une fois, toute nouvelle tentative de l'appeler,
par cette thread ou par une autre, doit lever
une exception IllegalStateException sera levée. De plus, après que l'enchère
soit finie, tout appel à bid() (ou à auction()) doit lever l'exception
IllegalStateException. Recopiez le code dans la classe Auction3 et faites
les modifications nécessaires pour implanter ce comportement.
© Université de Marne-la-Vallée