:: Enseignements :: Master :: M1 :: 2018-2019 :: Java Avancé ::
[LOGO]

Thread, Runnable, join, synchronized


Exercice 1 - Hello Thread

On souhaite créer 4 threads (le nombre peut changer) qui exécutent un même code affichant les nombres de 0 à 5 000.
Histoire de différencier les threads à l'affichage, chaque thread affichera en plus du nombre courant un numéro (0 pour la première thread, 1 pour la seconde, etc).
Par exemple, on pourra obtenir ce type d'affichage :
        ...
        hello 0 1714
        hello 0 1715
        hello 0 1716
        hello 0 1717
        hello 1 1096
        hello 1 1097
        hello 1 1098
        hello 1 1099
        ...
      

Rappel: créer un Runnable se fait en utilisant la syntaxe des lambdas, comme ceci
        Runnable runnable = () -> {
        ...
        };
      

  1. Rappeler à quoi sert un Runnable.
  2. Écrire, dans un premier temps, une classe HelloThread qui crée et démarre 4 threads qui affichent les nombres de 0 à 5 000 (sans le numéro unique par thread, donc).
  3. Exécutez le programme plusieurs fois, que remarque-t-on ?
    Puis, en regardant l'affichage (scroller au besoin), qu'y a-t-il de bizarre ?
    Est-ce que tout ceci est bien normal ?
  4. Modifiez votre code pour afficher en plus le numéro de chaque thread.
    Rappel : À l'intérieur d'une lambda, il n'est possible d'utiliser des variables déclarées à l'extérieur que si leur valeur ne change pas.

Exercice 2 - This is the end, my friend ...

On souhaite afficher le message "le programme est fini", lorsque toutes les threads ont fini de faire leurs calculs.

  1. Recopiez le programme de l'exercice précédent dans une nouvelle classe HelloThreadJoin puis modifiez le pour que soit affiché le message "le programme est fini" lorsque toutes les threads ont fini leurs calculs.
    Si vous cherchez comment attendre que des threads aient fini d'exécuter leur Runnable, la méthode que vous cherchez est Thread.join.
              Runnable runnable = () -> {
              ...
              };
              var thread = new Thread(runnable);
              thread.start();
              thread.join();
              System.out.println("La thread t a fini son Runnable");
            

Exercice 3 - When things add up

On souhaite modifier le programme précédent pour qu'au lieu d'afficher les nombres, on les stocke dans une unique ArrayList (une seule liste pour toutes les threads) de capacité initiale 20000=4*5000.
     var list = new ArrayList<Integer>(5000 * nbThreads);
  

  1. Recopiez la classe HelloThreadJoin dans une nouvelle classe HelloListBug puis modifiez-la pour y ajouter les nombres au lieu de les afficher. Faîtes afficher la taille finale de la liste, une fois toutes les threads terminées.
    Attention, les thread ne doivent plus faire d'affichage!
    Exécuter le programme plusieurs fois et noter les différents affichages.
  2. Expliquer comment la taille de la liste peut être plus petite que le nombre total d'appels à la méthode add. Pour comprendre, il faut regarder le code de la méthode ArrayList.add.
  3. Modifier votre code pour ne par fixer la capacité initiale de la liste.
        var list = new ArrayList<Integer>();
      
    Exécuter le programme plusieurs fois. Quel est le nouveau comportement observé ? Expliquer quel est le problème. Là encore, il faut regarder le code de la méthode ArrayList.add.
  4. Corriger le problème et vérifier que la correction que vous avez effectuée, exécute bien les threads en parallèle et non pas les unes derrière les autres.
  5. Votre code fait très probablement tout dans le main, ce qui n'est pas propre et ne correspond pas au bonnes pratiques vues en cours.
    Modifier votre code pour introduire une classe thread-safe nommée ThreadSafeList qui encapsule l'ArrayList et s'occupe de la concurrence.
    Comme cela votre main ne s'occupe plus directement de la gestion de la concurrence puisque c'est la classe ThreadSafeList qui le fait.
  6. Vérifier que la classe ThreadSafeList est bien thread-safe, quel que soit le code qui l'appelle (donc pas forcément le main que vous avez écrit).