Interuptions et Exceptions

Haut les mains!

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 = 2L; 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) {
    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.

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.

Remarque : il est possible pour un thread de demander à s'interrompre lui même ainsi : Thread.currentThread().interrupt();

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 ?

Count And Interrupt (à faire à la maison)

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 (exam 2017-2018)

"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.


Quelques indications :

Écrire le code de la classe ThePriceIsRight.