TP 13 Java

Richard Grin (grin@unice.fr) Retour TPs

Exercice 1 : Des threads indépendants

Un "compteur" a un nom (Toto par exemple) et il compte de 1 à n (nombre entier positif quelconque). Il marque une pause aléatoire entre chaque nombre (de 0 à 5000 millisecondes par exemple).

Un compteur affiche chaque nombre (Toto affichera par exemple, "Toto : 3") et il affiche un message du type "*** Toto a fini de compter jusqu'à 10" quand il a fini.

Ecrivez la classe compteur et testez-la en lançant plusieurs compteurs qui comptent jusqu'à 10. Voyez celui qui a fini le plus vite.

Correction

Compteur.java


Exercice 2 : Des threads un peu dépendants

Modifiez la classe Compteur pour que chaque compteur affiche son ordre d'arrivée : le message de fin est du type : "Toto a fini de compter jusqu'à 10 en position 3".

Correction

Compteur.java


Exercice 3 : Un problème d'accès concurrent

Voici 2 classes Compte (correspond à un compte bancaire) et Operation (thread qui effectue des opérations sur un compte bancaire).
 
  1. Examinez le code et faites exécuter la classe Opération. Constatez le problème : opération effectue des opérations qui devraient laisser le sode du compte inchangé, et pourtant, après un moment, le solde ne reste pas à 0. Expliquez.
  2. Modifiez le code pour empêcher ce problème.
  3. Dans le code de Operation, remplacez l'opération nulle par 2 opérations ajouter et retirer qui devraient elles aussi laisser le solde du compte à 0 (elles sont en commentaire dans le code). Lancez l'exécution et constatez le problème. Modifiez le code pour que ça marche.

Correction

Compte.java Operation.java
Pour la dernière question : Compte.java Operation.java


Exercice 4 : Tris parallèles

Voici un algorithme de tri en ordre croissant d'une tranche de tableau comprise entre les éléments d'indices debut et fin :

trier(debut, fin) {
  si (fin - debut < 2) {
    si (t[debut] > t[fin])
      echanger(t[i], t[j])
  }
  sinon {
    milieu = (i + j) / 2
    trier(debut, milieu)
    trier(milieu + 1, fin)
    triFusion(milieu) // tri fusion des 2 moitiés du tableau
  }
}

On remarque que les 2 tris qui sont effectués avant la fusion sont indépendants l'un de l'autre et il est donc facile des les faire exécuter en parallèle par 2 threads.

Voici une version Java mono-tâche de cet algorithme. Vous pouvez coder votre propre version si vous le souhaitez

En utilisant la méthode join(), codez une version multi-tâche de cet algorithme. Si vous lancez des threads depuis la méthode main(), n'oubliez pas d'attendre la fin de leur exécution avant d'afficher le résultat final (ceux pour lequel le tableau "trié" s'affiche tel qu'il était au début, pas trié, me comprendront !).

Correction

Trieur.java


Exercice 5 :

Codez une nouvelle version en utilisant cette fois-ci wait() - notify() au lieu de join().

Relancez plusieurs fois (au moins une dizaine de fois) votre programme pour essayer de repérer des éventuels problèmes liés au multi-tâche.

Correction

Trieur.java


Exercice 6 :

Si votre programme de l'exercice précédent marche parfaitement, bravo !

Pour vous montrer tout de même le type de problème que l'on peut rencontrer avec la programmation de plusieurs tâches, voici une classe qui induit ce type de problème. Lancez-la plusieurs fois jusqu'à obtenir un mauvais fonctionnement (blocage du programme).

Expliquez le problème et donnez une solution (vous l'avez peut-être déjà donnée dans votre programme de l'exercice précédent).

Correction

(C'est la même correction que l'exercice précédent)
Trieur.java


Pour ceux qui ont déjà fini....

Exercice 7 : Produit de 2 matrices en multi-tâches

Rappel : (Aij) . (Bkl) = (Pmn) avec Pmn = S (Amj . Bjn)

On remarque que les calculs des Pmn sont indépendants les uns des autres. On peut donc facilement effectuer ces calculs en parallèles.
Ecrivez une classe Matrice (n'implantez que les méthodes utiles pour effectuer le produit de 2 matrices en parallèle).

Correction

Matrice.java

Exercice 8 : Des threads un peu plus dépendants

Modifiez la classe Compteur de l'exercice 2 pour que chaque compteur donne un coup de pouce à un des autres compteurs (choisi au hasard) juste après avoir affiché un nombre : il interrompt la pause de cet autre compteur (pause entre l'affichage de 2 nombres), ce qui raccourcit le délai entre l'affichage de 2 nombres.

Correction

Compteur.java