"Hej, Amigo!"
"Og et par detaljer mere. Lad os kalde det praktiske råd."
"Antag, at du har en metode, der venter på noget og falder i søvn, indtil en betingelse er opfyldt."
public synchronized Runnable getJob()
{
if (jobs.size() == 0)
this.wait();
return jobs.remove(0);
}
"Java-dokumentationen anbefaler meget insisterende at kalde ventemetoden i en løkke:"
public synchronized Runnable getJob()
{
while (jobs.size() == 0)
this.wait();
return jobs.remove(0);
}
"Hvorfor? Sagen er, at hvis tråden vågner, betyder det ikke, at tilstanden er opfyldt. Måske var der tyve sådanne sovetråde. De vågnede alle sammen, men kun én kan tage opgaven."
"Der kan groft sagt være 'falske alarmer'. Det skal en god udvikler tage højde for."
"Jeg kan se. Er det ikke nemmere bare at bruge notify?"
"Nå, hvad nu hvis der var mere end én opgave på listen? Notify anbefales normalt at bruge af hensyn til optimeringen. I alle andre tilfælde anbefales det at bruge notifyAll metoden."
"OKAY."
"Men der er mere. For det første kan der være en situation, hvor nogen arver din klasse, tilføjer deres egne metoder og også bruger wait/notifyAll. Med andre ord kan der være en situation, hvor uafhængige wait/notifyAll-par venter på det samme objekt og kender ikke til hinanden. Så hvad skal du gøre?"
"Ring altid vente i en løkke og kontroller, at løkkens termineringsbetingelse er sand!"
"Godt. Og for at gøre det helt klart, at du ikke kan undslippe dette, påpeger mange udviklere, at nogle gange vågner tråde af sig selv. Tråde, der med garanti ikke vækkes ved et uheld. Dette ser ud til at være bivirkning af kodeoptimering i en kører Java-maskine."
"Wow. Okay. Uden en løkke er ventemetoden ikke god."
GO TO FULL VERSION