« Salut Amigo ! »
"Et quelques détails de plus. Appelons ça des conseils pratiques."
"Supposons que vous ayez une méthode qui attend quelque chose et s'endorme jusqu'à ce qu'une condition soit satisfaite."
public synchronized Runnable getJob()
{
if (jobs.size() == 0)
this.wait();
return jobs.remove(0);
}
"La documentation Java recommande très instamment d'appeler la méthode wait dans une boucle :"
public synchronized Runnable getJob()
{
while (jobs.size() == 0)
this.wait();
return jobs.remove(0);
}
"Pourquoi? Le fait est que si le fil se réveille, cela ne signifie pas que la condition est satisfaite. Peut-être qu'il y avait vingt de ces fils endormis. Tous se sont réveillés, mais un seul peut prendre la tâche."
"En gros, il peut y avoir de 'fausses alarmes'. Un bon développeur doit en tenir compte."
« Je vois. N'est-il pas plus facile d'utiliser simplement la notification ? »
"Eh bien, et s'il y avait plus d'une tâche dans la liste ? Il est généralement recommandé d'utiliser Notify à des fins d'optimisation. Dans tous les autres cas, il est recommandé d'utiliser la méthode notifyAll."
"D'ACCORD."
"Mais il y a plus. Premièrement, il peut y avoir une situation où quelqu'un hérite de votre classe, ajoute ses propres méthodes et utilise également wait/notifyAll. En d'autres termes, il peut y avoir une situation où des paires wait/notifyAll indépendantes attendent sur le même objet et ne se connaissent pas. Alors, que devriez-vous faire ? »
"Toujours appeler wait dans une boucle et vérifier que la condition de terminaison de la boucle est vraie !"
"D'accord. Et pour qu'il soit bien clair que vous ne pouvez pas échapper à cela, de nombreux développeurs soulignent que parfois les threads se réveillent d'eux-mêmes. Des threads qui sont garantis de ne pas être réveillés accidentellement. Cela semble être un effet secondaire de l'optimisation du code dans un machine Java en cours d'exécution."
"Whoa. J'ai compris. Sans boucle, la méthode d'attente n'est pas bonne."
GO TO FULL VERSION