:: Enseignements :: ESIPE :: E4INFO :: 2018-2019 :: Collections Concurrentes ::
[LOGO]

Concurrence Coopérative


Continuation, Fiber, Scheduler, Barrier et Lock

Exercice 1 - Scheduler Fifo

On souhaite écrire un scheduler simple qui puisse "scheduler" des Continuations suivant la politique du first in, first out.

  1. Qu'est ce que la concurrence coopérative ?
    Qu'elle sont ses avantages et ses inconvénients ?
  2. On souhaite implanter l'interface Scheduler (et sa classe compagnon SchedulerImpl), mais avant il faut comprendre ce que font les différentes méthodes. Pour cela ajouter les commentaires de documentation pour chacune des méthodes.
  3. Avant d'écrire la classe FifoScheduler qui implante l'interface scheduler et "schedule" les continuations dans l'ordre first in first out, écrivez un main de test avec deux continuations qui chacune font un yield.
  4. Ecrire le code de la classe FifoScheduler et vérifier que le main fonctionne correctement.

Exercice 2 - Barrier

On souhaite écrire une Barrier en utilisant la concurrence coopérative et le Scheduler de l'exercice précédent.

  1. Rappeler ce qu'est une barrière et son mode de fonctionnement (comme CyclicBarrier ou CountDownLatch).
  2. Implanter la classe Barrier et sa méthode await et tester en écrivant un main qui utilise le scheduler FifoScheduler.

Exercice 3 - Scheduler Random

On souhaite écrire un nouveau scheduler RandomScheduler qui sélectionne la Continuation a exécuter de façon alétoire.

  1. Recopier le main de la Barrier qui servira de test pour le scheduler.
  2. Implanter le scheduler RandomScheduler qui choisi la prochaine continuation à exécuter de façon aléatoire.
    Vous utiliserez java.util.ThreadLocalRandom comme générateur pseudo aléatoire.
  3. Le code de la Barrier garantie t'il que à la sortie de la Barrier n'importe qu'elle Continuation va s'exécuter ?
    Si ce n'est pas le cas, modifier le code de la Barrier.

Exercice 4 - Lock

On souhaite implanter la classe Lock qui est un verrou coopératif ré-entrant.

  public static void main(String[] args) {
    var scheduler = new RandomScheduler();
    var lock = new Lock(scheduler);
    var shared = new Object() {
      int x;
      int y;
    };

    IntStream.range(0, 2).forEach(id -> {
      scheduler.schedule(() -> {
        for (;;) {
          lock.lock();
          try {
            shared.x = id;
            //scheduler.pause();
            shared.y = id;
          } finally {
            lock.unlock();
          }
          //scheduler.pause();
        }
      });
    });
    scheduler.schedule(() -> {
      for (;;) {
        lock.lock();
        try {
          System.out.println(shared.x + " " + shared.y);
        } finally {
          lock.unlock();
        }
        //scheduler.pause();
      }
    });

    scheduler.loop();
  }
    

  1. En utilisant le main de test ci-dessus, écrire la classe Lock et ses méthodes lock et unlock sans se soucier de la ré-entrance
  2. Modifier votre implantation pour quelle soit ré-entrante et modifier le main pour tester la ré-entrance.

Exercice 5 - Exchanger

On souhaite écrire une classe Exchanger et sa méthode exchange en utilisant la concurrence coopérative.

  public static void main(String[] args) {
    var scheduler = new FifoScheduler();
    var exchanger = new Exchanger<String>(scheduler);
    scheduler.schedule(() -> {
      System.out.println("cont1: " + exchanger.exchange("hello"));
    });
    scheduler.schedule(() -> {
      System.out.println("cont2: " + exchanger.exchange("hi"));
    });
    scheduler.loop();
  }
   

Exercice 6 - Fibers

On souhaite utiliser le mécanisme de fibers à la place du mécanisme de threads dans un code déjà existant.