Frage

es wird im Java-Speichermodell erwähnt, dass:Wenn ein Thread einen synchronisierten Block im Rahmen der Freigabe des zugehörigen Monitors verlässt, erfordert das JMM, dass der lokale Prozessorcache in den Hauptspeicher geleert wird.Ähnlich, im Rahmen der Erfassung des Monitors beim Eingeben eines synchronisierten Blocks werden lokale Caches ungültig, sodass nachfolgende Lesevorgänge direkt in den Hauptspeicher und nicht in den lokalen Cache gehen.

warum also muss ich in diesem Code die Instanz als flüchtig deklarieren, da beim Betreten des zweiten Threads der Synchronisierungsblock direkt in den Hauptspeicher gelangt??

public final class MySingleton {
  private static MySingleton instance = null;
  private MySingleton() { } 
  public static MySingleton getInstance() {
    if (instance == null) {
      synchronized (MySingleton.class) {
        if (instance == null) {
          instance = new MySingleton();
        }
      }
    }
    return instance;
  }
}

Ich meine, wenn ein anderer Thread in den Synchronisationsblock eintritt und die zweite Überprüfung durchführt, soll er wie erwähnt aus dem Hauptspeicher aktualisiert werden.

War es hilfreich?

Lösung

Die Rennbedingung ist dies:

  1. Faden A sieht instance == NULL und führt diesen Code aus instance = new MySingleton();.Das schreiben an instance ist sichtbar, aber das schreibt hinein MySingleton sind noch nicht.

  2. Faden B sieht instance != NULL und beginnt an der Instanz zu arbeiten.

  3. Thread B arbeitet jetzt an einem Objekt, dessen Konstruktion er nicht sehen kann.

Wodurch instance volatile löst das Problem, da die JDK-Speicherspezifikation ab JDK5 garantiert, dass Schreibvorgänge in nichtflüchtige Objekte in Bezug auf Schreibvorgänge in ein flüchtiges Objekt nicht in der falschen Reihenfolge angezeigt werden.Also jeder Thread, der sieht instance != NULL muss die Instanz selbst sehen.

Andere Tipps

Sie müssen nicht volatil deklarieren, da sonst keine Garantie besteht, dass zwei Anrufe an getinstance () dieselbe Instanz zurückgeben werden.

Es gibt keine Garantie, dass der Hauptspeicher zugegriffen wird, nur ein cachekonsistenter Wert.d. H. Alle Threads sehen den gleichen Wert.

BTW: Sie wissen natürlich, dass es weitaus komplexer ist als nötig.Alles, was Sie brauchen, ist

generasacodicetagpre.

macht viel dasselbe.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top