14-ThreadEtExecutionSimultanee.html 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. <!DOCTYPE html>
  2. <html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
  3. <head>
  4. <meta charset="utf-8" />
  5. <meta name="generator" content="pandoc" />
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
  7. <title>Thread</title>
  8. <style type="text/css">
  9. code{white-space: pre-wrap;}
  10. span.smallcaps{font-variant: small-caps;}
  11. span.underline{text-decoration: underline;}
  12. div.column{display: inline-block; vertical-align: top; width: 50%;}
  13. </style>
  14. <link rel="stylesheet" href="pandoc.css">
  15. <!--[if lt IE 9]>
  16. <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
  17. <![endif]-->
  18. </head>
  19. <body>
  20. <div class="doctitle">Thread</div>
  21. <nav id="TOC">
  22. <ul>
  23. <li><a href="#thread-et-exécutions-concurrentes">Thread et exécutions concurrentes</a><ul>
  24. <li><a href="#introduction">Introduction</a></li>
  25. <li><a href="#observations">Observations</a><ul>
  26. <li><a href="#parallélisme">Parallélisme</a></li>
  27. <li><a href="#mise-en-pause-dun-thread">Mise en pause d’un Thread</a></li>
  28. <li><a href="#attente-de-fin-dexécution-dun-thread">Attente de fin d’exécution d’un Thread</a></li>
  29. <li><a href="#modification-conflictuelle-dune-même-ressource">Modification conflictuelle d’une même ressource</a></li>
  30. <li><a href="#exclusion-mutuelle-avec-synchronized">Exclusion mutuelle avec synchronized</a></li>
  31. <li><a href="#compte-en-banque-non-sécurisé">Compte en banque non sécurisé</a></li>
  32. <li><a href="#manipulation-de-comptes-mutuellement-exclusives">Manipulation de comptes mutuellement exclusives</a></li>
  33. <li><a href="#manipulation-de-comptes-mutuellement-exclusives-version-sans-boucle">Manipulation de comptes mutuellement exclusives version sans boucle</a></li>
  34. </ul></li>
  35. <li><a href="#exercices">Exercices</a><ul>
  36. <li><a href="#semaphore-et-lock">Semaphore et Lock</a></li>
  37. <li><a href="#le-problème-du-producteurconsommateur-verrou">Le problème du producteur/consommateur (verrou)</a></li>
  38. <li><a href="#le-problème-du-producteurconsommateur-moniteurs">Le problème du producteur/consommateur (moniteurs)</a></li>
  39. <li><a href="#application-des-countdownlatch-et-cyclicbarrier">Application des CountDownLatch et CyclicBarrier</a></li>
  40. </ul></li>
  41. <li><a href="#ressources">Ressources</a></li>
  42. </ul></li>
  43. </ul>
  44. </nav>
  45. <h1 id="thread-et-exécutions-concurrentes">Thread et exécutions concurrentes</h1>
  46. <h2 id="introduction">Introduction</h2>
  47. <p>De nos jours, les ordinateurs sont multi-tâches et sont capables d’exécuter plusieurs opérations simultanément (mise à jour en tâche de fond, contrôle de la bonne exécution d’une opération par une application tierce, etc).</p>
  48. <p>Il est fréquent que plusieurs acteurs accèdent de manière concurrente à une même ressource. Cela peut engendrer différents problèmes.</p>
  49. <h2 id="observations">Observations</h2>
  50. <h3 id="parallélisme">Parallélisme</h3>
  51. <p>Compiler et exécuter la classe <code>Thread1Parallelisme</code>.</p>
  52. <p>Le programme crée trois <em>threads</em> qui affichent 100 fois respectivement <code>Hello</code>, <code>World</code> et <code>and Everybody</code>.</p>
  53. <p>Que pouvez vous dire à propos de l’ordre d’affichage ? Expliquer.</p>
  54. <p><strong>Remarque</strong></p>
  55. <p>Ce programme hérite de <code>Thread</code> et réimplémente la méthode <code>run()</code> pour obtenir des flots d’exécutions parallèles.</p>
  56. <h3 id="mise-en-pause-dun-thread">Mise en pause d’un Thread</h3>
  57. <p>Compiler et exécuter plusieurs fois la classe <code>Thread2Sleep</code>.</p>
  58. <p>Voyez vous tous les affichages ?</p>
  59. <p>Essayez d’augmenter les valeurs d’attente (le troisième argument passé lors de la création des threads). Par quelle méthode de l’API Java est utilisé cette valeur ?</p>
  60. <p>Si vous mettez de trop grandes valeurs, vous devriez parfois ne plus voir aucun affichage.</p>
  61. <p><strong>Pourquoi ?</strong></p>
  62. <h3 id="attente-de-fin-dexécution-dun-thread">Attente de fin d’exécution d’un Thread</h3>
  63. <p>Dans la classe <code>Thread3Join</code>, nous faisons appel à la fonction join qui force le programme principal à attendre la terminaison des threads.</p>
  64. <p>Compiler le programme, Modifiez les valeurs d’attente (paramètre <code>delai</code>) et s’assurer que tous les affichages sont présents.</p>
  65. <h3 id="modification-conflictuelle-dune-même-ressource">Modification conflictuelle d’une même ressource</h3>
  66. <p>Dans la classe <code>Thread4ModificationConflictuelle</code>, nous manipulons une variable partagée d etype <code>Tableau</code>.</p>
  67. <p>Les Thread sont instanciés en leur donnant en paramètre un objet de type <code>Runnable</code> : la méthode <code>Runnable.run()</code> est exécutée par le Thread.</p>
  68. <p>Ces objets sont fabriqués par la classe <code>TacheTableau</code>. Deux types de tâches sont effectuées:</p>
  69. <ul>
  70. <li>les tâches <em>Déposer</em> incrémentent les valeurs dans le tableau</li>
  71. <li>les tâches <em>Retirer</em> décrémentent les valeurs dans le tableau</li>
  72. </ul>
  73. <p>Logiquement, à la fin les valeurs doivent être égales à 0 puisque les tâches incrémentant et décrementant s’annulent.</p>
  74. <p>Exécuter plusieurs fois le programme. Y a-t-il des cas où le résultat est différent ?</p>
  75. <h3 id="exclusion-mutuelle-avec-synchronized">Exclusion mutuelle avec synchronized</h3>
  76. <p>Pour corriger le problème dans l’exemple précédent, on ajoute le mot clé <code>synchronized</code> aux deux méthodes <code>incrementerValeurs</code> et <code>decrementerValeurs</code>.</p>
  77. <p>Exécuter le programme. S’assurer que le comportement est correct. Que remarquez vous au niveau du temps d’exécution ? Expliquer.</p>
  78. <h3 id="compte-en-banque-non-sécurisé">Compte en banque non sécurisé</h3>
  79. <p>Dans <code>Thread6CompteEnBanqueSansVerrou</code> la ressource partagée est un compte et non un tableau. Les opérations sont débiter, créditer et consulter.</p>
  80. <p>Est-ce que le solde est toujours égal à 0 à la fin ?</p>
  81. <h3 id="manipulation-de-comptes-mutuellement-exclusives">Manipulation de comptes mutuellement exclusives</h3>
  82. <p>Dans la classe <code>Thread7CompteSynchronized</code>, nous reprenons l’exemple de manipulation de comptes.</p>
  83. <p>Le programme est modifié pour interdire le retrait s’il n’y a pas assez d’argent.</p>
  84. <p>Quand le solde est insuffisant, les threads de retrait attendent (<code>wait()</code> dans la méthode <code>debiter</code>), ils sont réveillés par les threads de dépôt qui appellent la méthode <code>crediter</code> contenant un appel à <code>notify()</code>.</p>
  85. <p>Compiler et observer l’exécution de Thread7CompteSynchronized.</p>
  86. <p>Essayer de trouver un cas où un appel à retirer est fait avec un solde <code>0</code>. Que se passe-t-il ?</p>
  87. <h3 id="manipulation-de-comptes-mutuellement-exclusives-version-sans-boucle">Manipulation de comptes mutuellement exclusives version sans boucle</h3>
  88. <p>La classe <code>Thread8MutexSansBoucle</code> utilise <code>CompteMutexIf</code> est quasi identique à la classe <code>CompteMutex</code>.</p>
  89. <p>La différence tient dans le fait que pour la vérification de la condition avant <code>wait</code>, nous avons remplace le <code>while</code> par un <code>if</code>.</p>
  90. <p>Y a-t-il des cas où le solde devient négatif ? Expliquer.</p>
  91. <h2 id="exercices">Exercices</h2>
  92. <h3 id="semaphore-et-lock">Semaphore et Lock</h3>
  93. <p>Cet exercice est à faire initialement sur feuille papier, avant d’être programmé.</p>
  94. <p>Faites une recherche sur le concept de sémaphore dans le domaine du parallélisme.</p>
  95. <p>Etudiez la classe <code>DemoSemaphore</code>. Modifez les valeurs suivantes dans le <code>main</code>:</p>
  96. <ul>
  97. <li>paramètre <code>token</code> sur le constructeur</li>
  98. <li><code>numberOfLoops</code></li>
  99. </ul>
  100. <p>Observez ce qui se passe et concluez.</p>
  101. <p>Faites de même avec la classe <code>DemoLock</code>.</p>
  102. <p>Etudiez la documentation sur la classe <code>Semaphore</code>.</p>
  103. <p>Etudiez cette classe et l’interface <code>Lock</code> (et les classes qui l’implémentent).</p>
  104. <h3 id="le-problème-du-producteurconsommateur-verrou">Le problème du producteur/consommateur (verrou)</h3>
  105. <p>Programmer le problème du producteur/consommateur en utilisant les <code>Lock</code>. Pour cela, écrire une classe Stockage contenant un tableau d’Object ainsi que les méthodes <code>Object consomme()</code> et <code>void produit(Object)</code>.</p>
  106. <p>Écrire un programme principal qui instancie un objet Stockage puis qui crée de nombreux threads dont certains vont produire et d’autres consommer des objets.</p>
  107. <p>Faites en sorte que l’on puisse observer le déroulement des synchronisations (par exemple avec des <code>System.out.println()</code> judicieusement placés). Pour cela, vous aurez probablement à ralentir vos threads (en insérant des appels à <code>sleep(int)</code> à l’intérieur des sections critiques ou entre les productions/consommations d’objets).</p>
  108. <p>Note : vous pouvez utiliser la classe <code>Random</code> (voir la Javadoc) pour générer des temps d’attente aléatoires, ainsi que la classe <code>TimeUnit</code>.</p>
  109. <p>Gardez des traces montrant que certains threads sont effectivement endormis (et réveillés plus tard) lorsqu’ils essayent de consommer alors que le stockage est vide ou bien au contraire lorsqu’ils essayent de produire alors que le stockage est plein.</p>
  110. <h3 id="le-problème-du-producteurconsommateur-moniteurs">Le problème du producteur/consommateur (moniteurs)</h3>
  111. <p>Réécrivez le problème du producteur/consommateur en utilisant directement les moniteurs Java (i.e. sans utiliser la classe Semaphore ou Lock mais uniquement <code>synchronized</code>, <code>wait</code> et <code>notify</code>).</p>
  112. <h3 id="application-des-countdownlatch-et-cyclicbarrier">Application des CountDownLatch et CyclicBarrier</h3>
  113. <p>Ecrivez un programme simulant un repas fait par quatre convives (par l’affichage de messages).</p>
  114. <p>Les quatres convives doivent attendre d’être attablés avant de commencer le repas.</p>
  115. <p>Une fois le repas commencé, il se déroule comme suit:</p>
  116. <ul>
  117. <li>L’entrée est amenée. Les quatre convives mangent à des vitesses différentes (le premier met 2 minutes, le second 5 minutes, le troisième 3 minutes et le quatrième met 7 minutes).</li>
  118. <li>Une fois que tous les convives ont terminé leur entrée, le serveur enlève les assiettes vides.</li>
  119. <li>Le plat est alors amené et les quatre convives mangent également à des vitesses différentes (respectivement 4, 9, 6 et 5 minutes).</li>
  120. <li>Une fois le plat terminé par tous les convives il est desservi.</li>
  121. <li>Le café est alors servi et les convives mettent respectivement 2, 3, 1 et 4 minutes pour le boire.</li>
  122. <li>Le temps entre le moment où les convives ont terminé un met et le met suivant est servi est aléatoire (entre 1 et 15 minutes).</li>
  123. </ul>
  124. <p>Un serveur (géré par un Thread) enlève puis ramène les assiettes 2 par 2. Il met 1 minute pour effectuer un aller-retour en cuisine.</p>
  125. <p>Simulez ce repas (en remplaçant les minutes par des secondes pour plus de rapidité).</p>
  126. <p>Le programme doit inscrire dans un fichier les temps totaux d’exécution pour chaque repas (donc chaque lancement du programme).</p>
  127. <h2 id="ressources">Ressources</h2>
  128. <p>Un exemple d’utilisation de CyclicBarrier:</p>
  129. <p><a href="http://java67.blogspot.fr/2015/06/how-to-use-cyclicbarrier-in-java.html" class="uri">http://java67.blogspot.fr/2015/06/how-to-use-cyclicbarrier-in-java.html</a></p>
  130. <p>Une ressource pour les deux:</p>
  131. <p><a href="http://oppansource.com/cyclicbarrier-and-countdownlatch-in-java/" class="uri">http://oppansource.com/cyclicbarrier-and-countdownlatch-in-java/</a></p>
  132. <p>Un algorithme de tri parallèle:</p>
  133. <p><a href="http://www.javamex.com/tutorials/threads/CyclicBarrier_parallel_sort.shtml" class="uri">http://www.javamex.com/tutorials/threads/CyclicBarrier_parallel_sort.shtml</a></p>
  134. <p>Quelques explications sur l’usage de CountDownLatch:</p>
  135. <p><a href="http://howtodoinjava.com/2013/07/18/when-to-use-countdownlatch-java-concurrency-example-tutorial/" class="uri">http://howtodoinjava.com/2013/07/18/when-to-use-countdownlatch-java-concurrency-example-tutorial/</a></p>
  136. </body>
  137. </html>