"Bună, Amigo!"

„Există acest subiect uriaș – Modelul de memorie Java. Practic, nu trebuie să știi încă despre el, dar va fi util să auzi despre el.”

„Pentru a elimina toate problemele potențiale, Java și-a schimbat mecanismul de gestionare a memoriei. Acum memoria nu este pur și simplu împărțită în cache-ul local al unui fir și memoria globală – mecanismul este și mai bun.”

— Și mai complicat!

"Da, mai bine și mai complicat. E ca un avion. Zborul cu avionul este mai bine decât mersul pe jos, dar mai complicat. Voi încerca să explic noua situație foarte simplu."

„Iată ce au venit cu ei. La cod a fost adăugat un mecanism de sincronizare a memoriei firelor locale, numit „happens-before”. Au fost inventate mai multe reguli/condiții. Când aceste condiții sunt îndeplinite, memoria este sincronizată sau actualizată la curentul stat.

„Iată un exemplu:”

Ordin Firma 1 Firma 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;
}
Firul așteaptă ca mutexul să fie eliberat

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

„Una dintre aceste condiții este achiziția mutex-ului eliberat. Dacă un mutex este eliberat și re-dobândit, atunci memoria va fi sincronizată înainte de achiziție. Thread-ul 2 va vedea „cele mai recente” valori ale variabilelor x și y, chiar dacă nu le declari volatile”.

"Ce interesant! Și sunt multe dintre aceste condiții?"

„Destul – iată câteva condiții pentru sincronizarea memoriei:”

  • „Într-un singur fir, orice comandă are loc - înainte de orice operație care o urmează în codul sursă.”
  • „Eliberarea unui lacăt are loc înainte ca aceeași lacăt să fie obținută”.
  • „Se întâmplă o ieșire dintr-un bloc/metodă  sincronizat – înainte ca blocul/metoda sincronizat să fie introdus pe același monitor.”
  • „Scrierea unui câmp volatil în memorie are loc înainte ca același câmp volatil să fie citit din memorie.”
  • „Se întâmplă un sfârșit al metodei de rulare a unui obiect Thread – înainte ca metoda join() să se încheie sau metoda isAlive() returnează false pe obiectul din același fir.”
  • „Un apel la metoda start() a unui obiect Thread are loc – înainte ca metoda run() să înceapă pe obiectul din același fir.”
  • „Sfârșitul constructorului are loc înainte de începerea metodei finalize() a acestei clase.”
  • „Se întâmplă un apel la metoda interrupt() înainte ca firul de execuție să determină că această metodă a fost apelată, fie pentru că este lansată o excepție InterruptedException, fie prin utilizarea metodelor isInterrupted() sau interrupted()”.

„Deci, totul este un pic mai complicat decât credeam?”

"Da, ceva mai complicat..."

"Mulțumesc, Rishi. Mă voi gândi la asta."

„Nu vă faceți prea multe griji în legătură cu acest subiect. Va veni vremea când veți înțelege totul pe cont propriu. Deocamdată, ar fi mai bine să înțelegeți elementele de bază, decât să vă adânciți în pădurea deasă care este funcționarea internă a mașinii Java. Java 9 va fi lansat și apoi totul se va schimba din nou."

"O_o. Da... Unele lucruri este mai bine să nu le știi."