:: Enseignements :: ESIPE :: E4INFO :: 2018-2019 :: Java Inside ::
[LOGO]

Continuation


Continuation, Concurrence coopérative, Generator

Exercice 1 - Continuation

Le but de cet exercice est se familiariser avec la notion de Continuation.

  1. Créer un répertoire lab04 dans le repository java-inside
    Ajouter la version de pro "loom" à votre PATH
          export PATH=$PATH:/home/ens/forax/java-inside/pro-jdk-12-loom
        

    Exécuter pro scaffold dans le répertoire lab04 pour obtenir les fichiers de départ.
  2. Créer un projet Eclipse pointant sur le répertoire lab04 et faite en sorte que le JDK utiliser pour ce projet (dans Property > Build Path) pointe sur Pro (Pro est son propre JDK, c'est cool non ?)
  3. Dans Eclipse, créer une classe Example1 avec un main qui créé une continuation qui affiche "hello continuation", ayant pour scope "hello1" puis appel la méthode run sur la continuation.
  4. Ajouter un appel à Continuation.yield() avant l'affichage de "hello continuation".
    Que se passe-t'il ?
    Appeler une seconde fois la méthode run sur la continuation dans le main, Que se passe-t'il ?
  5. A votre avis comment fonctionne une continuation lorsque l'on appel Continuation.yield() et lorsque l'on appel run().
  6. Que se passe-t'il si on appel run() deux fois et qu'il n'y a pas d'appel à Continuation.yield() à l'intérieur du code de la continuation ?
    Est-ce le comportement que l'on attend ?
  7. Modifier le fichier .travis.yml pour que Travis test aussi le lab04.
  8. Quel est le comportement de l'appel Continuation.getCurrentContinuation(scope) lorsqu'on l'appel à l'intérieur du code de la continuation ou dans le main ?
    Comparer le comportement de Thread.currentThread() pour une Thread par rapport à Continuation.getCurrentContinuation pour une Continuation.
  9. Que se passe t'il lorsque l'on met un bloc synchronized autour d'un appel à Continuation.yield() ?
    Essayer d'expliquer ce comportement ?
  10. Il existe une méthode d'instance isDone sur une Continuation qui permet de savoir si le code d'une continuation a été complètement exécuter ou pas.
    Comment peut on s'en servir pour exécuter le code d'une continuation indépendamment du nombre d'appel à Continuation.yield à l'intérieur du code de la continuation.
    Modifier le code pour voir deux continuations qui exécute le même code et modifier le main pour que les deux continuations s'exécute alternativement.
  11. Qu'elle est la différence entre une Thread et une Continuation ?
  12. Créer une classe Scheduler
    • qui possède une méthode enqueue qui enregistre la continuation courante dans le Scheduler et fait un Continuation.yield().
      ou lève un beau message d'erreur si il n'y a pas de continuation courante.
    • qui possède une méthode runLoop qui en boucle, décide parmis les continuation enregistrées (les continuations en attente) quelle va être la prochaine continuation à exécuter et exécute celle-ci et s'arrête si il n'y a plus de continuation à exécuter.
    Pour l'instant on va dire que lorsque l'on doit choisir parmis plusieurs continuations, on prend la dernière qui s'est enregistrée.
  13. Modifier le scheduler pour qu'il prenne une politique d'exécution parmis:
    • STACK qui exécute la dernière continuation qui s'est enregistrée,
    • FIFO qui exécute la première continuation qui s'est enregistrée,
    • RANDOM qui exécute une continuation au hazard (Il existe une classe java.util.ThreadLocalRandom).

Exercice 2 - Generateur d'iterateur

Le but de cet exercice est d'implanter ce que l'appel un générateur qui est une méthode qui prend en paramètre un scheduler et un code à exécuter ayant lui même en paramètre un objet Yielder (qui possède une méthode yield qui renvoie une valeur) et renvoie un Iterator qui lorsque l'on parcourt execute le code passé en paramètre du generateur et renvoie lors d'un appel à next() la valeur renvoyé par l'appel à yield du Yielder.

  1. Créer une classe Generators avec une méthode generateIterator qui possède le comportement expliqué ci_dessus.
    Vous testerez en écrivant les tests unitaires dans la classe GeneratorsTests.

Exercice 3 - Test de performance [Optionel]

On souhaite quantifier le sur-coût d'utiliser un générateur par rapport à utiliser un itérateur codé la main lorsque l'on parcours une ArrayList.

  1. Ecrire un test JMH qui dans son constructeur créé une ArrayList d'Integer ayant 1 million d'entier (de 0 à 999_999) et une méthode testPlainIterator qui parcours la liste avec un Iterateur en utilisant une boucle for(:).
  2. Comparer la vitesse d'exécution de la méthode testPlainIterator avec une méthode testGeneratorIterator qui utilise la méthode generateIterator et la méthode ArrayList.forEach pour créer un itérateur qui fait le parcours.
  3. Que pouvez-vous en conclure ?