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

Rendez-vous et synchronization


Exercice 1 - Rendez vous (vous êtes cernés)

On souhaite écrire un petit programme qui permet de simuler le passage de paramètre entre une thread qui fait un calcul et la thread principale (celle qui exécute le main).

  1. Que se passe-t-il lorsqu'on exécute ce code ?
  2. Commenter l'instruction Thread.sleep(1) dans la méthode get puis ré-exécuter le code.
    Que se passe-t-il ?
    Expliquer où est le bug ?
  3. Écrire une classe RendezVous qui fonctionne comme la classe StupidRendezVous mais fonctionne correctement lorsque l'on commente l'instruction Thread.sleep(1).
  4. Regarder l'utilisation du CPU par votre programme avec la commande top. Rappeler ce qu'est une attente active, et expliquer pourquoi la classe RendezVous en est victime.
  5. Corriger le code de la classe RendezVous en utilisant les méthodes wait et notify pour éviter l'attente active. Regardez à nouveau l'utilisation du CPU par votre programme avec la commande top.
  6. Vérifiez que vous gérez les spurious wakeup correctement.

Exercice 2 - Exchanger

On souhaite implanter un Exchanger qui permet d'échanger deux valeurs entre deux threads.
L'idée est qu'une première thread va envoyer une valeur à l'Exchanger en utilisant la méthode exchange, celui-ci va bloquer la thread qui a fait appel à la méthode exchange et attendre (on suppose qu'il n'y a que 2 threads et que chacune appelle exchange exactement une fois). Lorsque une seconde thread fait elle aussi un appel à la méthode exchange avec une seconde valeur, l'appel retourne la première valeur envoyée et la première thread est dé-bloquée de son appel à exchange en retournant la seconde valeur (attention, les valeurs peuvent être nulles).
En fait, la classe Exchanger existe déjà en Java (dans le package java.util.concurrent), et voici un exemple de code l'utilisant.

On se propose donc de ré-implanter cette classe.

  1. Comment faire pour distinguer le premier et le second appel à la méthode exchange ?
  2. Écrire le code de la classe Exchanger.
  3. Modifier votre méthode d'échange pour encoder l'état de l'Exchanger avec un enum.
  4. Modifier le code pour utiliser les locks du package java.util.concurrent.locks.
    Il faut utiliser la classe Condition et bien garder en tête qu'il faut pas utiliser les méthodes Object.wait et Object.notify mais celles de Condition.
  5. L'Exchanger est-il utilisable plus d'une fois ?
    Autrement dit, on veut pouvoir exécuter un code comme celui-ci:
    et obtenir un affichage du type:
    thread 2 received from thread 0
    thread 0 received from thread 2
    thread 3 received from thread 8
    thread 8 received from thread 3
    thread 5 received from thread 9
    thread 9 received from thread 5
    thread 1 received from thread 7
    thread 7 received from thread 1
    thread 4 received from thread 6
    thread 6 received from thread 4
    
    Expliquer, en détail, ce qui se passe.
  6. Proposer une version réutilisable de l'Exchanger
    Indice: utiliser trois états permettant de savoir si l'échange n'est pas commencé, en cours ou fini
    Pour vous aider, nous vous donnons une version avec états d'un Exchanger non-réutilisable.