Frage

Ich habe einige Fragen zur AtomicReference.compareAndSet()-Methode. Laut Dokument hieß es:

Setzt den Wert atomar auf den angegebenen aktualisierten Wert, wenn der aktuelle Wert == der erwartete Wert ist.

Soweit ich weiß, ist das == Der Operator vergleicht die Adresse zweier Objekte. Wenn ja, wie funktioniert das in Beispielen wie diesem?

private AtomicReference<AccessStatistics> stats =
    new AtomicReference<AccessStatistics>(new AccessStatistics(0, 0));
public void incrementPageCount(boolean wasError) {
    AccessStatistics prev, newValue;
    do {
        prev = stats.get();
        int noPages = prev.getNoPages() + 1;
        int noErrors = prev.getNoErrors;
        if (wasError) {
           noErrors++;
        }
        newValue = new AccessStatistics(noPages, noErrors);
    } while (!stats.compareAndSet(prev, newValue));
}

Woher weiß JVM in diesem Codeausschnitt, welche Felder von AccessStatistics sind in der zu vergleichen compareAndSet()?Tatsächlich frage ich mich nur, wie diese ganze Strategie funktioniert, wenn Java kein Überschreiben zulässt == überhaupt?Vielen Dank für jeden Kommentar!

War es hilfreich?

Lösung

Woher weiß JVM, welche Felder von AccessStatistics im CompareAndSet() verglichen werden sollen?

Das ist nicht der Fall.Die Felder im Objekt werden nicht verglichen.Es ist nur ein Vergleich Referenz des Objekts, wie es in der Dokumentation steht.Genau so ist es AtomicReference Klasse funktioniert.Wie Sie aus dem erwähnen Javadocs, es benutzt == und nicht die equals() Methode.

Setzt den Wert atomar auf den angegebenen aktualisierten Wert, wenn der aktuelle Wert == der erwartete Wert ist.

Alle der Atomic* Klassen haben ähnliche Funktionen.Damit können Sie Werte atomar festlegen und gleichzeitig sicherstellen, dass ein anderer Thread Ihren Wert nicht überschreibt.Mit compareAndSet(...) Sie müssen die aktuelle Objektreferenz angeben, um sicherzustellen, dass die Aktualisierung wie erwartet erfolgt.

In Ihrem Codeausschnitt wird versucht, ein unveränderliches Zugriffsstatistikobjekt hinzuzufügen.Es ruft also den aktuellen Wert ab, addiert ihn dazu und speichert dann die neue Statistik in der Referenz.Wenn ein anderer Thread gespeichert ist es ist Statistiken zwischen dieser Zeit, dann die compareAndSet gibt „false“ zurück, durchläuft eine Schleife und versucht es erneut.Dies löst Rennbedingungen, ohne dass eine vorhanden sein muss synchronized Block.

Andere Tipps

Die JVM vergleicht die Felder überhaupt nicht.Es Nur vergleicht, ob es sich um dieselbe Referenz, denselben Zeiger im Speicher oder wie auch immer Sie ihn nennen möchten, handelt oder nicht.

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