Le

« Salut Amigo ! »

"Je veux approfondir avec vous concernant la notification d'attente. Les méthodes de notification d'attente fournissent un mécanisme pratique pour l'interaction des threads. Elles peuvent également être utilisées pour créer des mécanismes complexes de haut niveau pour l'interaction des threads."

"Je vais commencer par un petit exemple. Supposons que nous ayons un programme pour un serveur qui doit effectuer diverses tâches créées par les utilisateurs via un site Web. Les utilisateurs peuvent ajouter diverses tâches à différents moments. Les tâches sont gourmandes en ressources, mais notre serveur 8 -le processeur principal peut faire face. Comment devrions-nous effectuer les tâches sur le serveur ?"

"D'abord, nous allons créer un groupe de threads de travail, autant qu'il y a de cœurs de processeur. Chaque thread pourra s'exécuter sur son propre cœur : les threads n'interféreront pas les uns avec les autres et les cœurs de processeur ne reste assis sans rien faire."

"Deuxièmement, nous allons créer un objet de file d'attente où les tâches des utilisateurs seront ajoutées. Différents types de tâches correspondront à différents objets, mais tous implémenteront l'interface Runnable afin qu'ils puissent être exécutés."

« Pourriez-vous me donner un exemple d'objet de tâche ? »

"Vérifiez-le:"

Une classe qui calcule n factorielle lorsque la méthode run() est appelée
class Factorial implements Runnable
{
 public int n = 0;
 public long result = 1;

 public Factorial (int n)
 {
  this.n = n;
 }

 public void run()
 {
  for (int i = 2; i <= n; i++)
   result *= i;
 }
}

"Jusqu'ici, tout va bien."

« Super. Alors examinons à quoi devrait ressembler un objet file d'attente. Que pouvez-vous m'en dire ?

"Il doit être thread-safe. Il est chargé avec des objets de tâche par un thread qui les reçoit des utilisateurs, puis les tâches sont récupérées par les threads de travail."

"Ouais. Et si nous manquions de tâches pendant un certain temps?"

"Ensuite, les threads de travail doivent attendre qu'il y en ait d'autres."

"C'est vrai. Imaginez maintenant que tout cela peut être construit dans une seule file d'attente. Vérifiez-le :"

Une file d'attente de tâches. S'il n'y a pas de tâches, le thread s'endort et attend qu'une tâche apparaisse :
public class JobQueue
{
 ArrayList jobs = new ArrayList();

 public synchronized void put(Runnable job)
 {
  jobs.add(job);
  this.notifyAll();
 }

 public synchronized Runnable getJob()
 {
  while (jobs.size() == 0)
   this.wait();

  return jobs.remove(0);
 }
}

"Nous avons une méthode getJob qui vérifie si la liste des tâches est vide. Le thread se met alors en veille (attend) jusqu'à ce que quelque chose apparaisse dans la liste."

"Il existe également la méthode put , qui permet d'ajouter une nouvelle tâche à la liste. Dès qu'une nouvelle tâche est ajoutée, la méthode notifyAll est appelée. L'appel de cette méthode réveille tous les threads de travail qui se sont endormis dans la méthode getJob."

« Pouvez-vous vous rappeler comment fonctionnent les méthodes d'attente et de notification ? »

"La méthode d'attente n'est appelée qu'à l'intérieur d'un bloc synchronisé, sur un objet mutex. Dans notre cas : ceci. De plus, deux choses se produisent :

1) Le fil s'endort.

2) Le thread libère temporairement le mutex (jusqu'à ce qu'il se réveille).

"Après cela, d'autres threads peuvent entrer dans le bloc synchronisé et acquérir ce même mutex."

"La méthode notifyAll ne peut également être appelée qu'à l'intérieur du bloc synchronisé d'un objet mutex. Dans notre cas : ceci. De plus, deux choses se produisent :"

1) Tous les threads en attente sur cet objet mutex sont réveillés.

2) Une fois que le thread actuel quitte le bloc synchronisé, l'un des threads réveillés acquiert le mutex et continue son travail. Lorsqu'il libère le mutex, un autre thread réveillé acquiert le mutex, etc.

"C'est très similaire à un bus. Vous entrez et vous voulez payer votre course, mais il n'y a pas de chauffeur. Alors vous vous «endormez». Finalement, le bus est bondé, mais il n'y a toujours personne à qui donner la course. Puis le chauffeur arrive et dit: "Tarif, s'il vous plaît". Et c'est le début de…"

"Comparaison intéressante. Mais qu'est-ce qu'un bus ?"

"Julio a expliqué cela. Il y avait ces choses étranges utilisées au 21e siècle."