Flüchtige Garantien und nicht ordnungsgemäße Ausführung [Duplikat]

Diese Frage hat hier bereits eine Antwort:

Java-Speichermodell: Flüchtige Variablen und Vorkommnisse 3 Antworten

WICHTIGE ÄNDERUNG Ich weiß über das "passiert bevor"in dem Thread, in dem die beiden Zuweisungen stattfinden Meine Frage ist, ob es möglich wäreEin weiterer Thread liest "b" ungleich Null, während "a" immer noch Null ist. Das weiß ich also, wenn Sie anrufenTu es() aus demselben Thread wie dem, in dem Sie zuvor angerufen habensetBothNonNull (...) dann kann es keine NullPointerException auslösen. Aber was ist, wenn man anruft?Tu es() von einem anderen Thread als derjenige, der anruftsetBothNonNull (...) ?

Beachten Sie, dass es sich bei dieser Frage ausschließlich um die handeltvolatile Stichwort und dievolatile garantiert: es istnicht über diesynchronized Schlüsselwort (bitte antworten Sie nicht mit "Sie müssen synchronisieren", da ich kein Problem zu lösen habe: Ich möchte das einfach verstehenvolatile Garantien (oder fehlende Garantien) in Bezug auf die nicht ordnungsgemäße Ausführung).

Angenommen, wir haben ein Objekt, das zwei enthältvolatile Zeichenfolgenverweise, die vom Konstruktor auf null initialisiert werden und die nur auf eine Weise geändert werden können: durch AufrufensetBoth (...) und dass wir ihre Referenzen später nur auf Nicht-Null-Referenzen setzen können (nur der Konstruktor darf sie auf Null setzen).

Zum Beispiel (es ist nur ein Beispiel, es gibt noch keine Frage):

public class SO {

    private volatile String a;
    private volatile String b;

    public SO() {
        a = null;
        b = null;
    }

    public void setBothNonNull( @NotNull final String one, @NotNull final String two ) {
        a = one;
        b = two;
    }

    public String getA() {
        return a;
    }

    public String getB() {
        return b;
    }

}

ImsetBothNoNull (...)erscheint die Zeile, die den Nicht-Null-Parameter "a" zuweist, vor der Zeile, die den Nicht-Null-Parameter "b" zuweist.

Dann, wenn ich das tue (noch einmal, es gibt keine Frage, die Frage kommt als nächstes):

doIt() {
    if ( so.getB() != null ) {
        System.out.println( so.getA().length );
    }
}

Habe ich nach meinem Verständnis Recht, dass ich aufgrund einer nicht ordnungsgemäßen Ausführung eine bekommen kann?NullPointerException?

Mit anderen Worten: Es gibt keine Garantie, dass ich, weil ich ein Nicht-Null "b" lese, ein Nicht-Null "a" lese.

Denn wegen Out-of-Order (Multi) Prozessor und dem Wegvolatile Werke "b" könnten vor "a" vergeben werden?

volatile Garantien, dass nach einem Schreibzugriff immer der zuletzt geschriebene Wert angezeigt wird, aber hier liegt ein "Problem" außerhalb der Reihenfolge vor, oder? (Noch einmal, das "Problem" ist absichtlich gemacht, um zu versuchen, die Semantik der zu verstehenvolatile Stichwort und das Java Memory Model, um ein Problem nicht zu lösen).

Antworten auf die Frage(5)

Ihre Antwort auf die Frage