« Salut Amigo ! »

« Salut, Rishi ! »

"Je vais vous présenter les méthodes wait , notify et notifyAll de la classe Object."

"Aujourd'hui, nous allons simplement nous familiariser avec eux, mais nous reviendrons plus tard et passerons plus de temps là-dessus."

"D'accord."

"Ces méthodes ont été inventées dans le cadre du mécanisme de synchronisation des threads."

"Permettez-moi de vous rappeler que Java dispose d'un mécanisme intégré pour contrôler l'accès aux ressources partagées (objets) à partir de différents threads. Un thread peut déclarer qu'un objet est occupé, et les autres threads devront attendre que l'objet occupé soit libéré. "

"Je m'en souviens. Vous faites cela en utilisant le mot clé synchronized ."

"Bien. En règle générale, le code ressemblerait à ceci :"

public void print()
{
 Object monitor = getMonitor();
 synchronized(monitor)
 {
  System.out.println("text");
 }
}

"Tu te souviens comment ça marche ?"

"Oui. Si deux threads appellent simultanément la méthode print(), l'un d'eux entrera dans le bloc étiqueté synchronisé et verrouillera le moniteur, ce qui fait que le deuxième thread attendra que le moniteur soit libéré."

"Bien. Une fois qu'un thread entre dans le bloc étiqueté synchronisé, l'objet moniteur est marqué comme occupé et les autres threads seront forcés d'attendre que l'objet moniteur soit libéré. ​​Le même objet moniteur peut être utilisé dans différentes parties du programme. "

« Au fait, pourquoi avez-vous choisi le nom de moniteur ? »

"Un moniteur est ce que vous appelez habituellement un objet qui stocke l'état occupé ou libre."

"Et c'est là que les méthodes d'attente et de notification entrent en jeu."

"En fait, ce sont vraiment les deux seules méthodes. Les autres ne sont que des adaptations de ces méthodes."

"Maintenant, voyons ce qu'est la méthode d'attente et pourquoi nous en avons besoin. "

"Parfois, il y a des situations dans un programme où un thread entre dans un bloc de code synchronisé et verrouille le moniteur, mais ne peut pas continuer parce qu'il manque des données. Par exemple, un fichier qu'il doit traiter n'a pas fini de se télécharger ou quelque chose comme ca."

"Nous pourrions simplement attendre que le fichier soit téléchargé. Vous pouvez simplement le vérifier à l'aide d'une boucle. Si le fichier n'a pas encore été téléchargé, alors dormez environ une seconde et vérifiez à nouveau jusqu'à ce qu'il soit téléchargé."

"Quelque chose comme ça:"

while(!file.isDownloaded())
{
 Thread.sleep(1000);
}
processFile(file);

"Mais dans notre cas, ce type d'attente est trop coûteux. Puisque notre thread a verrouillé le moniteur, d'autres threads sont également obligés d'attendre même s'ils ont peut-être déjà les données dont ils ont besoin."

"La méthode wait () a été inventée pour résoudre ce problème. Cette méthode oblige le thread à libérer le moniteur, puis à "suspendre" le thread.

"Vous ne pouvez appeler la méthode d'attente d'un objet moniteur que lorsque le moniteur est occupé, c'est-à-dire uniquement à l'intérieur d'un bloc synchronisé . Lorsque cela se produit, le thread s'arrête temporairement et le moniteur est libéré afin que d'autres threads puissent l'utiliser."

"Il y a souvent des cas où un thread entrera dans un bloc synchronisé et appellera en attente, libérant ainsi le moniteur."

"Ensuite, un deuxième fil entrera et sera suspendu, puis un troisième, et ainsi de suite."

"Et comment un fil est-il repris?"

« Pour cela, il existe une seconde méthode : notifier.

"Vous ne pouvez appeler les méthodes notify / notifyAll d'un objet moniteur que lorsque le moniteur est occupé, c'est-à-dire uniquement à l'intérieur d'un bloc synchronisé . La méthode notifyAll réveille tous les threads en attente sur cet objet moniteur."

"La méthode de notification "dégèle" un thread aléatoire, mais la méthode notifyAll dégèle tous les threads "gelés" de ce moniteur."

"Très intéressant. Merci, Rishi."

"Il existe également des adaptations de la méthode wait() :"

méthode d'attente () Explication
void wait(long timeout)
Le thread « se fige », mais il se « débloque » automatiquement après avoir attendu le nombre de millisecondes passé à la méthode en argument.
void wait(long timeout, int nanos)
Le thread « se fige », mais il se « débloque » automatiquement après avoir attendu le nombre de nanosecondes passé à la méthode en argument.

"Nous appelons également cela une attente avec un délai d'attente. La méthode fonctionne comme une attente normale, mais si le temps spécifié s'est écoulé et que le thread n'a pas été réveillé, il se réveille lui-même."