"Ciao, Amico!"

"C'è questo enorme argomento là fuori: il Java Memory Model. Fondamentalmente, non devi ancora saperlo, ma sarà utile sentirlo."

"Per eliminare tutti i potenziali problemi, Java ha cambiato il suo meccanismo di gestione della memoria. Ora la memoria non è semplicemente divisa in cache locale di un thread e memoria globale: il meccanismo è ancora migliore."

"E più complicato!"

"Sì, meglio e più complicato. È come un aeroplano. Volare in aereo è meglio che camminare, ma più complicato. Cercherò di spiegare la nuova situazione in modo molto semplice."

"Ecco cosa hanno escogitato. Al codice è stato aggiunto un meccanismo per sincronizzare la memoria del thread locale, chiamato 'happens-before'. Sono state inventate diverse regole/condizioni. Quando queste condizioni sono soddisfatte, la memoria viene sincronizzata o aggiornata all'attuale stato.

"Ecco un esempio:"

Ordine Discussione 1 Filo 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;
}
Il thread è in attesa del rilascio del mutex

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

"Una di queste condizioni è l'acquisizione del mutex rilasciato. Se un mutex viene rilasciato e riacquisito, la memoria verrà sincronizzata prima dell'acquisizione. Il thread 2 vedrà i valori 'più recenti' delle variabili x e y, anche se non li dichiari volatili."

"Che interessante! E ci sono molte di queste condizioni?"

"Basta, ecco alcune condizioni per sincronizzare la memoria:"

  • "All'interno di un singolo thread, qualsiasi comando viene eseguito prima di qualsiasi operazione che lo segue nel codice sorgente."
  • "Il rilascio di un blocco avviene prima che lo stesso blocco venga acquisito."
  • "Si verifica un'uscita da un blocco/metodo  sincronizzato , prima che il blocco/metodo sincronizzato venga inserito sullo stesso monitor."
  • "La scrittura di un campo volatile nella memoria avviene prima che lo stesso campo volatile venga letto dalla memoria."
  • "Si verifica la fine del metodo run di un oggetto Thread , prima che il metodo join() termini o che il metodo isAlive() restituisca false sull'oggetto nello stesso thread."
  • "Si verifica una chiamata al metodo start() di un oggetto Thread , prima che il metodo run() venga avviato sull'oggetto nello stesso thread."
  • "La fine del costruttore avviene prima dell'inizio del metodo finalize() di questa classe."
  • "Si verifica una chiamata al metodo interrupt() , prima che il thread determini che questo metodo è stato chiamato, perché viene generata un'eccezione Interrupted() o utilizzando i metodi isInterrupted() o interrupt()."

"Allora, è tutto un po' più complicato di quanto pensassi?"

"Sì, un po' più complicato..."

"Grazie, Rishi. Ci penserò."

"Non preoccuparti troppo di questo argomento. Verrà il momento in cui capirai tutto da solo. Per ora, sarebbe meglio che tu capissi le basi, piuttosto che addentrarti nella fitta foresta che è il funzionamento interno della macchina Java. Java 9 verrà rilasciato e poi tutto cambierà di nuovo."

"O_o. Sì... Certe cose è meglio non saperle."