Exercice 1 : voir source corrigé. Pour la question 3, on a intérêt : a) à placer *tout* le code de gestion de la course dans un Thread (GestionCourse, Arbitre...) ça simplifie le code b) il serait plus sûr de modifier ainsi AfficheurResultat : public class AfficheurResultat { public static void afficher(String titre, String message) { SwingUtilities.invokeLater(new ShowMessageHelper(titre,message)); } } class ShowMessageHelper implements Runnable { String titre; String message; public ShowMessageHelper(String titre, String message) { this.titre = titre; this.message = message; } /* (non-Javadoc) * @see java.lang.Runnable#run() */ public void run() { JOptionPane.showMessageDialog( null, titre, message, JOptionPane.PLAIN_MESSAGE); } } Exercice 2 : * Question 1 : Deux threads, T1 et T2, empilent chacun une valeur dans une pile vide. T1 fait "push(3)". La première ligne de push est exécutée, et la case 0 contient la valeur 3. T2 fait push(10) : la case 0 contient maintenant 10. T2 fait nombreElts++ : nombreElts passe à 1. T1 fait nombreElts++ : nombreElts passe à 2. On a donc au final, une pile qui contient 10 dans la case 0, et 0 dans les autres, et dont la taille annoncée est 2. Question 2 : Non. p.isFull() et p.push(v) sont sûres, mais leur combinaison ne l'est pas. Si un autre thread rempli la pile entre l'exécution des deux commandes, le programme plante. Question 3 : Question à corriger après quelques temps, car elle n'est pas si facile : Par exemple : synchronized void push(int v) { // On attend que p ne soit plus pleine while (p.isFull()) { } // On ajoute vals[nombreElts]= v; nombreElts++; } bloque tout : à partir du moment où on rentre dans la méthode, on ne peut plus appeler pop (puisque pop est aussi synchronisée). Une solution possible est : synchronized void push(int v) { boolean notDone= true; while (notDone) { synchronized (this) { // On attend que p ne soit plus pleine if (! p.isFull()) { // On ajoute vals[nombreElts]= v; nombreElts++; notDone= false; } } } } Exercice 3 : On ajoute un tableau "classement" à CourseEscargotModele, ainsi qu'un entier "nbrClasses", initialement à 0. //Ajoute au classement l'escargot numero i : synchronized void ajouterClassement(int i) { classement[nbrClasses++]= i; } synchronized boolean courseTerminee() { return nbrClasses == 3; } Et dans EscargotControle : while (escargot().getX() < modele.getDistance() && ! modele.courseTerminee()) { ... } Exercice 4 : Correction ci-dessous. Notez que pour la dernière question, il peut être intéressant de disposer d'une méthode pop() "traditionnelle", qui récupère la valeur du sommet de la pile *et* qui dépile ; cela simplifie le code (en l'absence de cette méthode, on doit synchroniser).