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 le premier thread,
1 pour la second, 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 ...
Runnable
se fait en utilisant la syntaxe des lambdas,
comme ceci
Runnable runnable = () -> { ... };
name
ou setName
. Rappeler à quoi sert un Runnable
.
Écrire, dans un premier temps, une classe HelloThread
qui crée et démarre 4 threads (et faire en sorte qu'on puisse facilement en demander 150)
qui affichent les nombres de 0 à 5 000 (sans le numéro unique par thread, donc).
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 ?
Modifiez votre code pour afficher en plus le numéro de chaque thread (sans utiliser le numéro du thread, juste la variable de boucle).
On souhaite afficher le message "le programme est fini"
,
lorsque tous les threads ont fini de faire leurs calculs.
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 tous les threads ont fini leurs calculs.
Runnable
, la méthode que vous cherchez est la méthode d'instance join
.
Runnable runnable = () -> { ... }; var thread = Thread.ofPlatform().start(runnable); thread.join(); System.out.println("Le thread a fini son Runnable");
On veut réaliser une classe TurtleRace
dont un squellette du main
est donné ci-dessous :
public static void main(String[] args) throws InterruptedException { System.out.println("On your mark!"); Thread.sleep(30_000); System.out.println("Go!"); int[] times = {25_000, 10_000, 20_000, 5_000, 50_000, 60_000}; ... }
Le main
attend 30 000 millisecondes (i.e., 30 secondes) puis devra lancer autant de threads qu'il y a de valeurs dans le tableau times
. Le premier thread s'appelera Turtle0
est attendra times[0]
(c'est à dire 25 000 millisecondes) avant d'afficher Turtle 0 has finished
. Le second thread attendra times[1]
millesecondes avant d'afficher Turtle 1 has finished
. Et ainsi de suite ...
Réaliser la classe TurtleRace
. Bien entendu, votre code doit fonctionner si l'on modifie le tableau times
.
Vous devriez avoir comme un affichage qui ressemble à ça :
On your mark! Go! Turtle 3 has finished Turtle 1 has finished Turtle 2 has finished Turtle 0 has finished Turtle 4 has finished Turtle 5 has finished
sleep
est dépendant du système. Elle ne peut en aucun cas servir à garantir l'ordre d’exécution des threads.Juste après avoir exécuté la classe TurtleRace
, lancez jconsole dans un terminal.
$ /usr/local/apps/java11/bin/jconsole
Il faut se connecter sur la classe TurtleRace
et accepter le warning sur la connexion non-sécurisée. Vous devriez avoir ce genre d'affichage :
Observer l'évolution du nombre de threads. Que devient le thread main
? Quand est-ce que la JVM s'éteint ?
System.out.println
La classe HelloThreadBis
est une solution à la première question de l'exercice 1. La seule différence notable avec votre solution devrait être qu'au lieu d'utiliser System.out.println
, nous avons recodé une fonction qui réalise l'affichage de la chaîne, caractère par caractère.
public static void println(String s){ for(var i = 0; i < s.length(); i++){ System.out.print(s.charAt(i)); } System.out.print("\n"); }
HelloThreadBis
et comparer la sortie avec ce que vous avez obtenu avec la classe HelloThread
de l'exercice 1.HelloThreadBis
des lignes comme celle-ci :
hello 4725 hello 4726 hellhello 4889 hello 4890 hello 4891 hello 4892 hello 4893 hello 4894 hello 4895 hello 4896 hello 4897 hello 4898 hello 4899 hello 4900 hello 4901 hello 4902 hello 4903 o 4hello 4904 hello 4905
System.out.println
? System.out.println