"Hej, Amigo!"

"Och ett par detaljer till. Låt oss kalla det praktiska råd."

"Anta att du har en metod som väntar på något och somnar tills ett tillstånd är uppfyllt."

Om samlingen är tom, så väntar vi
public synchronized Runnable getJob()
{
 if (jobs.size() == 0)
  this.wait();

 return jobs.remove(0);
}

"Java-dokumentationen rekommenderar mycket enträget att man anropar väntemetoden i en loop:"

Om samlingen är tom, så väntar vi
public synchronized Runnable getJob()
{
 while (jobs.size() == 0)
  this.wait();

 return jobs.remove(0);
}

"Varför? Saken är den att om tråden vaknar så betyder det inte att tillståndet är uppfyllt. Det kanske fanns tjugo sådana sovtrådar. Alla vaknade, men bara en kan ta uppgiften."

"I grova drag kan det vara "falskt larm". En bra utvecklare måste ta hänsyn till detta."

"Jag förstår. Är det inte lättare att bara använda notify?"

"Tja, tänk om det fanns mer än en uppgift i listan? Notify rekommenderas vanligtvis att använda för optimeringens skull. I alla andra fall rekommenderas det att använda notifyAll-metoden."

"OK."

"Men det finns mer. För det första kan det finnas en situation där någon ärver din klass, lägger till sina egna metoder och även använder wait/notifyAll. Med andra ord kan det finnas en situation där oberoende wait/notifyAll-par väntar på samma objekt och vet inte om varandra. Så vad ska du göra?"

"Ring alltid vänta i en loop och kontrollera att slingans termineringsvillkor är sant!"

"Och för att göra det helt klart att du inte kan undgå detta, påpekar många utvecklare att ibland vaknar trådar av sig själva. Trådar som garanterat inte väcks av misstag. Detta verkar vara en bieffekt av kodoptimering i en kör Java-maskin."

"Wow. Jag förstår. Utan en loop är väntemetoden inte bra."