"Hej, Amigo!"

"Det finns det här enorma ämnet där ute - Java Memory Model. I grund och botten behöver du inte veta om det ännu, men det kommer att vara bra att höra om det."

"För att eliminera alla potentiella problem ändrade Java sin minneshanteringsmekanism. Nu är minnet inte bara uppdelat i en tråds lokala cache och globala minne - mekanismen är ännu bättre."

"Och mer komplicerat!"

"Ja, bättre och mer komplicerat. Det är som ett flygplan. Att flyga med flyg är bättre än att gå, men mer komplicerat. Jag ska försöka förklara den nya situationen väldigt enkelt."

"Här är vad de kom fram till. En mekanism för att synkronisera lokalt trådminne, kallad 'händer-före', lades till i koden. Flera regler/villkor uppfanns. När dessa villkor är uppfyllda synkroniseras eller uppdateras minnet till nuvarande stat.

"Här är ett exempel:"

Beställa Tråd 1 Tråd 2
1
2

101
102
103
104
105

201
202
203
204
205
public int y = 1;
public int x = 1;

x = 2;
synchronized(mutex)
{
 y = 2;
}
Tråden väntar på att mutex ska släppas

synchronized(mutex)
{
 if (y == x)
 System.out.println("YES");
}

"Ett av dessa villkor är förvärvet av den frigjorda mutexen. Om en mutex släpps och återanskaffas, kommer minnet att synkroniseras före förvärvet. Tråd 2 kommer att se de 'senaste' värdena för variablerna x och y, även om du förklarar dem inte flyktiga."

"Hur intressant! Och finns det många av dessa förhållanden?"

"Nog – här är några villkor för att synkronisera minne:"

  • "Inom en enda tråd händer vilket kommando som helst - före varje operation som följer det i källkoden."
  • "Lösningen av ett lås sker - innan samma lås har förvärvats."
  • "En utgång från ett synkroniserat block/metod  sker - innan det synkroniserade blocket/metoden skrivs in på samma monitor."
  • "Skrivningen av ett flyktigt fält till minnet sker - innan samma flyktiga fält läses från minnet."
  • "Ett slut på ett Thread-objekts körningsmetod inträffar - innan join()-metoden slutar eller metoden isAlive() returnerar false på objektet i samma tråd."
  • "Ett anrop till ett Thread-objekts start()-metod händer-innan run()-metoden startar på objektet i samma tråd."
  • "Slutet av konstruktorn händer-före början av den här klassens finalize()-metod."
  • "Ett anrop till metoden interrupt() händer-innan tråden bestämmer att den här metoden har anropats, antingen för att ett InterruptedException kastas eller genom att använda metoderna isInterrupted() eller interrupted()."

"Så, det hela är lite mer komplicerat än jag trodde?"

"Ja, lite mer komplicerat..."

"Tack, Rishi. Jag ska tänka på det."

"Oroa dig inte för mycket om det här ämnet. Tiden kommer när du kommer att förstå allt på egen hand. För nu vore det bättre för dig att förstå grunderna, snarare än att gräva ner i den täta skogen som är Java-maskinens interna funktion. Java 9 kommer att släppas och sedan kommer allt att förändras igen."

"O_o. Ja... Vissa saker är det bättre att inte veta."