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

Thread, Runnable, join, synchronized, interrupt


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 r = () -> {
        ...
        };
      

  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 toutesles 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 r = () -> {
              ...
              };
              Thread t = new Thread(r);
              t.start();
              t.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.
     ArrayList<Integer> list = new ArrayList<>(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.
         ArrayList<Integer> list = new ArrayList<>();
      
    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 respecte-t-il les bonnes pratiques vues en cours sur l'utilisation des locks. Si ce n'est pas déjà le cas, donner une version respectant ces bonnes pratiques.