:: Enseignements :: ESIPE :: E4INFO :: 2017-2018 :: Concurrence ::
[LOGO]

TP Note de Concurrence


Le but de ce TP est d'écrire une classe Quorum permettant de simuler le fonctionnement d'un simple algorithme de consensus. Dans les avions, lorsqu'un calcul doit être effectué, celui-ci est effectué sur plusieurs processeurs (de marques différentes) utilisant des programmes différents mais respectant la même spécification. L'idée est que, si un programme (ou un processeur) a un bug, comme le même calcul est fait par les autres processeurs, on peut détecter l'erreur et ne pas tenir compte du résultat d'un calcul défectueux.
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é.
Attention à bien lire le sujet en entier.

Exercice 1 - Quorum

Les tests JUnit pour toutes les questions du TP sont dans la classe QuorumTest.java.
Attention, les tests sont volontairement simples pour que vous puissiez les lires. Ils peuvent reporter des erreurs sur la console au lieu de reporter les erreurs dans la partie graphique. Donc un test passe s'il est vert et qu'il ne fait pas d'erreur sur la console.

On cherche à écrire une classe Quorum et son unique méthode vote dont le but est de simuler la recherche d'une valeur de consensus par plusieurs threads, où chaque thread vote pour une valeur qui est le résultat d'un calcul, pour faire simple, on supposera que le résultat est toujours un int. L'algorithme est le suivant:
  • Si deux threads votent pour la même valeur, alors la valeur de retour de vote pour les deux threads sera cette valeur. Bien sûr, si une seule thread vote, il faut attendre la seconde thread, au moins.
  • Si les deux threads ont voté des valeurs différentes, on attend alors la valeur d'une troisième thread.
  • Si deux threads sur les 3 ont voté pour une même valeur, alors cette valeur est renvoyée par les 3 threads.
  • Dans le cas où les 3 valeurs sont différentes, alors l'exception IllegalStateException est levée (dans un avion, on va rebooter les calculateurs).
Dans le cas où plus de trois thread votent, les valeurs votées supplémentaires ne sont pas prises en compte et la valeur de consensus précédemment trouvée est renvoyée. Dans le cas où l'exception IllegalStateException a été levée, toute nouvelle thread qui vote lévera aussi l'exception IllegalStateException. Bref, une fois le consensus établi, on ne peut pas le changer.
Enfin, si une des threads qui votent est en attente et est interrompue, alors toute les threads en attente vont lever l'exception IllegalStateException. De même, toute nouvelle thread qui voudra voter recevra l'exception IllegalStateException.

L'API de la classe Quorum est donc la suivante
    public class Quorum {
      public int vote(int value) throws IllegalStateException {
        //TODO
      }
    }
   
Vous n'avez pas le droit d'ajouter des méthodes publiques dans cette classe.

  1. Écrire la classe Quorum sans ce soucier de la gestion des interruptions et en utilisant les blocs synchronized.
  2. Ajouter la gestion des interruptions.
  3. Copier/coller le code de votre classe Quorum dans une classe OldQuorum pour faire une sauvegarde. Puis modifier le code de la classe Quorum pour utiliser les verrous du package java.util.concurrent.lock plutôt que les blocs synchronized.
  4. (Bonus - à ne faire que si tout le reste semble fonctionner parfaitement) On cherche maintenant à écrire une classe MajorityQuorum et son unique méthode vote dont le but est de simuler la recherche d'une valeur de consensus par un nombre indéfini de threads. La règle est qu'un consensus est trouvé dès qu'une majorité (la moitié plus une) de threads qui ont déjà voté sont d'accord. Comme précédemment, si un consensus a déjà été trouvé, c'est cette valeur que renverra une nouvelle thread qui souhaite voter.
    Écrire et tester la classe MajorityQuorum correspondante.