L'examen est composé d'une partie écrite sur feuille de 45 minutes maximum, à faire en premier et d'un exercice qui doit être traité ensuite.
Rappel : si ce n'est pas déjà le cas, 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.
La javadoc 25 est là : https://igm.univ-mlv.fr/~juge/javadoc-25/.
Vous avez le droit de consulter les transparents du cours pendant tout l'examen.
Les classes de cet exercice doivent être dans package fr.uge.concurrence.exo1.
Dans cet exercice, on cherche à simuler un
En dehors du bateau (sur les rives), les loups et les chèvres peuvent rester ensemble sans danger (ils sont dans des enclos différents).
On va créer une classe thread-safe SafeBoat qui va permettre à plusieurs threads, représentant les animaux, de traverser la rivière. Un objet de la classe SafeBoat est construit avec une capacité capacity. La classe SafeBoat possède une méthode public boolean board(Animal animal) dont le paramètre indique quel type d'animal essaie d'embarquer :
public enum Animal {
LOUP, CHEVRE
}
Lorsqu'un animal appelle board(), soit il embarque immédiatement dans le bateau, soit il est refusé parce qu'un animal de l'autre type est déjà à bord, et dans ce cas la méthode renvoie false. Tant qu'il n'y a pas capacity animaux (threads) sur le bateau, tous les threads embarqués attendent. Une fois que capactity threads-animaux du même type sont dans le bateau, ces threads sont débloqués et descendent du bateau. Dans ce cas, la méthode renvoie true. Une fois que tous les animaux sont descendus du bateau, il est à nouveau possible, pour n'importe quel type d'animal, d'embarquer sur le bateau.
À tout moment, on doit pouvoir savoir quels sont les threads qui sont déjà sur le bateau et en attente que capacity animaux soient là. Pour cela, la classe SafeBoat possède une méthode public Set<Thread> inBoat() qui permet d'obtenir cette information.
L'exercice comporte 5 questions.
Écrire la classe thread-safe SafeBoat, son constructeur et ses méthodes board et inBoat en utilisant des blocs synchronized.
Dans la classe SafeBoat, écrire un main permettant d'utiliser un SafeBoat avec une capacité de 4. Il y aura 10 threads représentant des loups et 10 threads représentant des chèvres. Chaque thread attend en utilisant la fonction waitRandom(1000) (voir code ci-dessous) avant d'appeler board() une seule fois. Il affiche qu'il est là avant d'essayer d'embarquer. S'il n'y arrive pas, il affiche qu'il n'y a pas de bateau, sinon, après avoir traversé, il affiche qu'il a réussi.
Ajouter un autre thread watcher qui, après avoir attendu 1000 ms, affiche toutes les 200 ms les thread qui sont dans le bateau.
Remarquez qu'il est possible que le programme ne s'arrête pas, s'il y des threads bloqués sur le bateau et plus aucun thread du même type qui essaie d'embarquer. C'est normal, on essaiera de régler ce problème plus tard.
public static void waitRandom(int time) throws InterruptedException {
Thread.sleep(time + Math.abs(ThreadLocalRandom.current().nextInt() % time));
}
Vous devriez avoir un affichage similaire à ceci :
LOUP 1 vient d'arriver. CHEVRE 1 vient d'arriver. Pas de bateau pour CHEVRE 1 Sur le bateau : [Thread[#36,LOUP 1,5,main]] LOUP 9 vient d'arriver. LOUP 0 vient d'arriver. CHEVRE 8 vient d'arriver. Pas de bateau pour CHEVRE 8 LOUP 8 vient d'arriver. LOUP 1 a traversé et est descendu. LOUP 8 a traversé et est descendu. LOUP 9 a traversé et est descendu. LOUP 0 a traversé et est descendu. CHEVRE 4 vient d'arriver. Sur le bateau : [Thread[#29,CHEVRE 4,5,main]] LOUP 2 vient d'arriver. Pas de bateau pour LOUP 2 CHEVRE 2 vient d'arriver. LOUP 7 vient d'arriver. Pas de bateau pour LOUP 7 CHEVRE 6 vient d'arriver. CHEVRE 7 vient d'arriver. CHEVRE 7 a traversé et est descendue. CHEVRE 4 a traversé et est descendue. CHEVRE 2 a traversé et est descendue. CHEVRE 6 a traversé et est descendue. LOUP 4 vient d'arriver. Sur le bateau : [Thread[#39,LOUP 4,5,main]] CHEVRE 3 vient d'arriver. Pas de bateau pour CHEVRE 3 LOUP 5 vient d'arriver. Sur le bateau : [Thread[#39,LOUP 4,5,main], Thread[#40,LOUP 5,5,main]] LOUP 3 vient d'arriver. CHEVRE 5 vient d'arriver. Pas de bateau pour CHEVRE 5 LOUP 6 vient d'arriver. LOUP 6 a traversé et est descendu. LOUP 5 a traversé et est descendu. LOUP 3 a traversé et est descendu. LOUP 4 a traversé et est descendu. CHEVRE 0 vient d'arriver. CHEVRE 9 vient d'arriver. Sur le bateau : [Thread[#25,CHEVRE 0,5,main], Thread[#34,CHEVRE 9,5,main]] Sur le bateau : [Thread[#25,CHEVRE 0,5,main], Thread[#34,CHEVRE 9,5,main]] ...
Le propriétaire du bateau voudrait connaître les statistiques de son business de transport.
Copiez votre code dans une classe SafeBoat2 et modifier la classe SafeBoat2, ainsi que le code du main pour que le thread watcher puisse afficher simultanément le nombre d'animaux sur le bateau et le nombre de chèvres et de loups qui ont traversé jusqu'à présent.
LOUP 9 vient d'arriver. CHEVRE 0 vient d'arriver. Pas de bateau pour CHEVRE 0 CHEVRE 7 vient d'arriver. Pas de bateau pour CHEVRE 7 CHEVRE 6 vient d'arriver. Pas de bateau pour CHEVRE 6 LOUP 1 vient d'arriver. LOUP 3 vient d'arriver. Sur le bateau : 2. Sur l'autre rive : 0 chèvres, 0 loups. CHEVRE 5 vient d'arriver. Pas de bateau pour CHEVRE 5 LOUP 0 vient d'arriver. LOUP 0 a traversé et est descendu. LOUP 3 a traversé et est descendu. LOUP 1 a traversé et est descendu. LOUP 9 a traversé et est descendu. CHEVRE 1 vient d'arriver. LOUP 6 vient d'arriver. Pas de bateau pour LOUP 6 CHEVRE 4 vient d'arriver. Sur le bateau : 2. Sur l'autre rive : 0 chèvres, 4 loups. LOUP 5 vient d'arriver. Pas de bateau pour LOUP 5 LOUP 2 vient d'arriver. Pas de bateau pour LOUP 2 LOUP 8 vient d'arriver. Pas de bateau pour LOUP 8 LOUP 4 vient d'arriver. Pas de bateau pour LOUP 4 Sur le bateau : 2. Sur l'autre rive : 0 chèvres, 4 loups. CHEVRE 8 vient d'arriver. LOUP 7 vient d'arriver. Pas de bateau pour LOUP 7 CHEVRE 3 vient d'arriver. Sur le bateau : 3. Sur l'autre rive : 0 chèvres, 4 loups. CHEVRE 3 a traversé et est descendue. CHEVRE 4 a traversé et est descendue. CHEVRE 8 a traversé et est descendue. CHEVRE 1 a traversé et est descendue. CHEVRE 2 vient d'arriver. CHEVRE 9 vient d'arriver. Sur le bateau : 2. Sur l'autre rive : 4 chèvres, 4 loups. Sur le bateau : 2. Sur l'autre rive : 4 chèvres, 4 loups.
Le propriétaire du bateau est toutefois un peu nerveux : avec ce système, s'il n'y a pas assez d'animaux pour remplir les conditions d'un voyage, le bateau risque d'attendre indéfiniment. Il se propose de veiller lui-même à ce que cela n'arrive pas. Chaque 2000 ms, il vérifie ses comptes. S'il y a des animaux qui attendent sur le bateau et si le nombre d'animaux sur l'autre rive n'a pas changé depuis la dernière vérification, il fait partir le bateau.
Modifier le code de SafeBoat2 en conséquence et ajouter un thread correspondant au propriétaire. L'objectif étant que le programme se termine, faire en sorte que le thread watcher et celui du prioritaire n'empêchent pas le programme de s'arrêter.
CHEVRE 9 vient d'arriver. LOUP 4 vient d'arriver. Pas de bateau pour LOUP 4 LOUP 7 vient d'arriver. Pas de bateau pour LOUP 7 CHEVRE 5 vient d'arriver. Sur le bateau : 2. Sur l'autre rive : 0 chèvres, 0 loups. CHEVRE 4 vient d'arriver. Sur le bateau : 3. Sur l'autre rive : 0 chèvres, 0 loups. LOUP 6 vient d'arriver. Pas de bateau pour LOUP 6 CHEVRE 3 vient d'arriver. CHEVRE 3 a traversé et est descendue. CHEVRE 9 a traversé et est descendue. CHEVRE 5 a traversé et est descendue. CHEVRE 4 a traversé et est descendue. LOUP 1 vient d'arriver. Sur le bateau : 1. Sur l'autre rive : 4 chèvres, 0 loups. CHEVRE 8 vient d'arriver. Pas de bateau pour CHEVRE 8 CHEVRE 0 vient d'arriver. Pas de bateau pour CHEVRE 0 LOUP 8 vient d'arriver. CHEVRE 1 vient d'arriver. Pas de bateau pour CHEVRE 1 LOUP 5 vient d'arriver. CHEVRE 7 vient d'arriver. Pas de bateau pour CHEVRE 7 CHEVRE 2 vient d'arriver. Pas de bateau pour CHEVRE 2 LOUP 0 vient d'arriver. LOUP 8 a traversé et est descendu. LOUP 1 a traversé et est descendu. LOUP 0 a traversé et est descendu. LOUP 5 a traversé et est descendu. Sur le bateau : 0. Sur l'autre rive : 4 chèvres, 4 loups. LOUP 3 vient d'arriver. LOUP 2 vient d'arriver. LOUP 9 vient d'arriver. CHEVRE 6 vient d'arriver. Pas de bateau pour CHEVRE 6 Sur le bateau : 3. Sur l'autre rive : 4 chèvres, 4 loups. Sur le bateau : 3. Sur l'autre rive : 4 chèvres, 4 loups. Sur le bateau : 3. Sur l'autre rive : 4 chèvres, 4 loups. Sur le bateau : 3. Sur l'autre rive : 4 chèvres, 4 loups. Sur le bateau : 3. Sur l'autre rive : 4 chèvres, 4 loups. Sur le bateau : 3. Sur l'autre rive : 4 chèvres, 4 loups. départ forcé : non Sur le bateau : 3. Sur l'autre rive : 4 chèvres, 4 loups. Sur le bateau : 3. Sur l'autre rive : 4 chèvres, 4 loups. Sur le bateau : 3. Sur l'autre rive : 4 chèvres, 4 loups. Sur le bateau : 3. Sur l'autre rive : 4 chèvres, 4 loups. Sur le bateau : 3. Sur l'autre rive : 4 chèvres, 4 loups. Sur le bateau : 3. Sur l'autre rive : 4 chèvres, 4 loups. Sur le bateau : 3. Sur l'autre rive : 4 chèvres, 4 loups. Sur le bateau : 3. Sur l'autre rive : 4 chèvres, 4 loups. Sur le bateau : 3. Sur l'autre rive : 4 chèvres, 4 loups. Sur le bateau : 3. Sur l'autre rive : 4 chèvres, 4 loups. Sur le bateau : 3. Sur l'autre rive : 4 chèvres, 4 loups. Sur le bateau : 3. Sur l'autre rive : 4 chèvres, 4 loups. Sur le bateau : 3. Sur l'autre rive : 4 chèvres, 4 loups. Sur le bateau : 3. Sur l'autre rive : 4 chèvres, 4 loups. départ forcé : oui LOUP 3 a traversé et est descendu. LOUP 2 a traversé et est descendu. LOUP 9 a traversé et est descendu.
Le propriétaire n'est pas satisfait de son modèle car il "perd" tous les animaux qui arrivent alors qu'un autre type d'animal est dans le bateau. Il souhaite que la méthode board() fasse attendre les animaux jusqu'à ce que que le bateau ait traversé, afin qu'ils puissent essayer d'embarquer quand le bateau est revenu.
Copier le code des questions 1 et 2 (SafeBoat) dans une classe SafeBoat3 et modifier le code de SafeBoat3 pour obtenir ce comportement.