„Hallo, Amigo!“

„Es gibt da draußen dieses riesige Thema – das Java-Speichermodell. Im Grunde müssen Sie noch nichts davon wissen, aber es wird hilfreich sein, davon zu hören.“

„Um alle potenziellen Probleme zu beseitigen, hat Java seinen Speicherverwaltungsmechanismus geändert. Jetzt wird der Speicher nicht einfach in den lokalen Cache eines Threads und den globalen Speicher aufgeteilt – der Mechanismus ist sogar noch besser.“

„Und komplizierter!“

„Ja, besser und komplizierter. Es ist wie mit einem Flugzeug. Mit dem Flugzeug fliegen ist besser als zu Fuß, aber komplizierter. Ich werde versuchen, die neue Situation ganz einfach zu erklären.“

„Hier ist, was sie sich ausgedacht haben. Dem Code wurde ein Mechanismus zur Synchronisierung des lokalen Thread-Speichers namens „Happens-Before“ hinzugefügt. Es wurden mehrere Regeln/Bedingungen erfunden. Wenn diese Bedingungen erfüllt sind, wird der Speicher synchronisiert oder auf den aktuellen Stand gebracht Zustand.

„Hier ist ein Beispiel:“

Befehl Thread 1 Thread 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;
}
Der Thread wartet auf die Freigabe des Mutex

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

„Eine dieser Bedingungen ist die Erfassung des freigegebenen Mutex. Wenn ein Mutex freigegeben und erneut erfasst wird, wird der Speicher vor der Erfassung synchronisiert. Thread 2 sieht die „neuesten“ Werte der Variablen x und y, auch wenn Sie erklären sie nicht für flüchtig.

„Wie interessant! Und gibt es viele dieser Bedingungen?“

„Genug – hier sind einige Bedingungen für die Speichersynchronisierung:“

  • „Innerhalb eines einzelnen Threads wird jeder Befehl ausgeführt – vor jeder Operation, die ihm im Quellcode folgt.“
  • „Die Freigabe einer Sperre erfolgt, bevor dieselbe Sperre erworben wird.“
  • „Ein Verlassen eines synchronisierten Blocks/einer synchronisierten Methode  erfolgt, bevor der synchronisierte Block/die synchronisierte Methode auf demselben Monitor eingegeben wird.“
  • „Das Schreiben eines flüchtigen Felds in den Speicher erfolgt, bevor dasselbe flüchtige Feld aus dem Speicher gelesen wird.“
  • „Die Ausführungsmethode eines Thread-Objekts wird beendet, bevor die Methode „join()“ endet oder die Methode „isAlive()“ für das Objekt im selben Thread „false“ zurückgibt.“
  • „Ein Aufruf der start()-Methode eines Thread-Objekts erfolgt, bevor die run()-Methode für das Objekt im selben Thread startet.“
  • „Das Ende des Konstruktors findet vor dem Beginn der finalize()-Methode dieser Klasse statt.“
  • „Ein Aufruf der Interrupt()-Methode erfolgt, bevor der Thread feststellt, dass diese Methode aufgerufen wurde, entweder weil eine InterruptedException ausgelöst wird oder indem die Methoden isInterrupted() oder interrupted() verwendet werden.“

„Also ist alles etwas komplizierter als ich dachte?“

„Ja, etwas komplizierter…“

„Danke, Rishi. Ich werde darüber nachdenken.“

„Machen Sie sich nicht zu viele Gedanken über dieses Thema. Es wird die Zeit kommen, in der Sie alles selbst verstehen werden. Für den Moment ist es besser, wenn Sie die Grundlagen verstehen, anstatt in den dichten Wald einzutauchen, der das ist.“ interne Abläufe der Java-Maschine. Java 9 wird veröffentlicht und dann wird sich alles wieder ändern.

„O_o. Ja... Manche Dinge sollte man besser nicht wissen.“