Dans cet exercice, on cherche à comprendre le fonctionnement des interruptions.
Pourquoi n'est il pas possible d’arrêter un thread de façon non coopérative ?
Rappeler ce qu'est un appel de méthode bloquant.
À quoi sert la méthode d'instance interrupt() de la classe Thread?
Expliquer comment interrompre un thread en train d'effectuer un appel de méthode bloquant et le faire sur l'exemple suivant : le thread main attend 5 secondes avant d'interrompre le thread qui dort et ce dernier affiche son nom.
public static void main(String[] args) {
Thread.ofPlatform().start(() -> {
for (var i = 1;; i++) {
try {
Thread.sleep(1_000);
System.out.println("Thread slept " + i + " seconds.");
} catch (InterruptedException e) {
// TODO
}
}
});
}
Expliquer, sur l'exemple suivant, comment utiliser la méthode
Thread.interrupted pour arrêter le calcul de findPrime() qui n'est pas une méthode bloquante. Modifier le code de findPrime (mais ni sa signature, ni isPrime) pour pouvoir l'interrompre. Dans ce cas, elle renvoie un OptionalLong vide.
Puis faire en sorte que le main attende 3 secondes avant d'interrompre le thread qui cherche un nombre premier, en affichant "STOP".
public static boolean isPrime(long candidate) {
if (candidate <= 1) {
return false;
}
for (var i = 2; i <= Math.sqrt(candidate); i++) {
if (candidate % i == 0) {
return false;
}
}
return true;
}
public static OptionalLong findPrime() {
var generator = ThreadLocalRandom.current();
for (;;) {
var candidate = generator.nextLong();
if (isPrime(candidate)) {
return OptionalLong.of(candidate);
}
}
}
public static void main(String[] args) throws InterruptedException {
Thread.ofPlatform().start(() -> {
System.out.println("Found a random prime : " + findPrime().orElseThrow());
});
}
Expliquer la (trop) subtile différence entre les méthodes Thread.interrupted et thread.isInterrupted de la classe Thread.
Attention, dans ce cours, vous n'avez pas le droit d'utiliser thread.isInterrupted.
On souhaite maintenant faire en sorte que findPrime s'arrête dès que possible si le thread qui l’utilise est interrompu. Pour cela, modifier le code de findPrime et/ou isPrime sans modifier leur signature.
Et si vous pouvez modifier le code des méthodes ET leur signature, que faites-vous ?
Pouvez-vous garantir que le programme afichera soit un nombre, soit "STOP", mais pas les deux ?
On souhaite avoir 4 threads qui affichent chacun leur numéro et un compteur indéfiniment (chaque thread a son propre compteur). Pour éviter de faire chauffer la machine, l'affichage se fera une fois par seconde (en utilisant Thread.sleep()).
De plus, le thread main va lire des entiers sur l'entrée standard
et si l'utilisateur entre une valeur correspondant au numéro d'un thread,
ce dernier sera arrêté.
Le code pour lire sur l'entrée standard est le suivant :
System.out.println("enter a thread id:");
try (var input = new InputStreamReader(System.in);
var reader = new BufferedReader(input)) {
String line;
while ((line = reader.readLine()) != null) {
var threadId = Integer.parseInt(line);
...
}
}
Rappel : on utilise Ctrl-D (Ctrl-Z sous Microsoft Windows) pour indiquer au terminal
qu'il faut fermer l'entrée standard.
Comment faire pour que le programme se termine si l'on fait un Ctrl-D dans le terminal ?
"Le Juste Prix", The price is right en anglais, est un jeu télévisé ou plusieurs candidats s'affrontent pour gagner un article (dont le prix n'est pas connu par les candidats). Chaque candidat propose un prix et le candidat qui indique le prix le plus proche du prix réel d'un article gagne cet article.
Dans cet exercice, vous devez implanter la même mécanique de jeu avec un thread simulant un candidat.
Les tests JUnit pour toutes les questions de l'exercice sont dans la classe
ThePriceIsRightTest.java.
Attention, les tests sont volontairement simples pour que vous puissiez les lires.
Ils peuvent reporter des erreurs sur la console au lieu de reporter les erreurs dans la partie graphique.
Donc un test passe s'il est vert et qu'il ne fait pas d'erreur sur la console.
ThePriceIsRight est initialisé avec le prix réel de l'article, ainsi que le nombre de candidats.
var thePriceIsRight = new ThePriceIsRight(100, 2);
propose prend en paramètre un entier qui correspond au prix proposé par un candidat (un thread). Cette méthode bloque tant que tous les candidats n'ont pas soumis leur prix puis elle renvoie true au thread qui a proposé le prix le plus proche et false à tous les autres threads.
propose,
la proposition de prix des threads supplémentaires ne sera pas prise en compte et la méthode propose renvoie false.
propose renvoie false.
false.
private int distance(int price) {
return Math.abs(price - realPrice);
}
Stream, vous pouvez utiliser le collector Collectors.minBy,
mais vous pouvez aussi écrire le code à la main, pourvu que ce soit correct.
Écrire le code de la classe ThePriceIsRight.