Das Markieren einer Variablen als volatile
in Java stellt sicher, dass jedem Thread der Wert angezeigt wird, der zuletzt geschrieben wurde, und nicht ein veralteter Wert. Ich habe mich gefragt, wie das tatsächlich erreicht wird. Gibt die JVM spezielle Anweisungen aus, die die CPU-Kisten oder etwas ähnliches löschen?
Nach meinem Verständnis sieht es immer so aus, als wäre der Cache nach dem Schreiben geleert worden und erscheint immer so, als ob Lesevorgänge direkt aus dem Speicher gelesen werden. Der Effekt ist, dass ein Thread immer die Ergebnisse von Schreibvorgängen von einem anderen Thread und (gemäß dem Java Memory Model) niemals einen zwischengespeicherten Wert sieht. Die tatsächliche Implementierung und CPU-Anweisungen variieren jedoch von Architektur zu Architektur.
Es garantiert keine Korrektheit, wenn Sie die Variable in mehr als einem Thread inkrementieren, oder überprüfen Sie ihren Wert und einige Maßnahmen ergreifen, da offensichtlich keine tatsächliche Synchronisation ist. Sie können im Allgemeinen nur die korrekte Ausführung garantieren, wenn nur Thread in die Variable schreibt und alle anderen lesen.
Beachten Sie auch, dass eine nicht-volatile 64-Bit-Variable als zwei 32-Bit-Variablen gelesen / geschrieben werden kann, so dass die 32-Bit-Variablen beim Schreiben atomar sind, die 64-Bit-Variablen jedoch nicht. Eine Hälfte kann vor einer anderen geschrieben werden - also kann der gelesene Wert unter dem alten oder dem neuen Wert liegen.
Dies ist eine sehr hilfreiche Seite aus meinen Lesezeichen:
Was genau passiert, ist prozessorspezifisch. Im Allgemeinen gibt es eine Form von Speicherbarrierenanweisungen. Das Leeren des gesamten Cachespeichers wäre natürlich sehr teuer - es gibt Cache-Kohärenzprotokolle in der Hardware.
Wichtig ist auch, dass bestimmte Optimierungen nicht über die Feldzugriffe hinweg vorgenommen werden. Der Compiler ist wichtig, wenn Sie Multithreading in Betracht ziehen, denken Sie nicht nur an die Hardware.
Tags und Links java concurrency volatile