Meine Frage betrifft sichere Veröffentlichung von Feldwerte in Java (wie hier erläutert Java multi-threading & Safe Publication).Sichere Veröffentlichung, wenn Werte in synchronisierten Methoden gelesen werden
Wie ich es verstehe, kann ein Feld sicher gelesen werden (Zugriff von mehreren Threads Bedeutung wird den richtigen Wert sehen), wenn:
- Lese- und Schreib auf demselben Monitor synchronisiert
- Feld endgültig
- Feld ist flüchtig
Wenn mein Verständnis korrekt die folgende Klasse ist, sollte nicht, da die Thread-sicher sein Der Anfangswert wird ohne diese Merkmale geschrieben. Allerdings kann ich kaum glauben, dass ich first
volatile
machen muss, obwohl nur von einer synchronized
Methode zugegriffen wird.
public class Foo {
private boolean needsGreeting = true;
public synchronized void greet() {
if (needsGreeting) {
System.out.println("hello");
needsGreeting = false;
}
}
}
Fehle ich etwas? Ist der obige Code korrekt und wenn ja, warum? Oder ist es in solchen Fällen notwendig, first
volatile
oder verwenden Sie eine final AtomicBoolean
oder etwas Ähnliches zusätzlich für den Zugriff von einer synchronized
Methode.
(Nur um zu klären, ich weiß, dass, wenn der Anfangswert in einem Verfahren synchronized
geschrieben wurde, wäre es Thread-sicher auch ohne volatile
Schlüsselwort sein.)
"[...] was bedeutet, dass es keine zufällige-vor-Kante vom Ende eines Konstruktors eines Objekts bis zum Anfang einer beliebigen Methode gibt!". Diese "Implikation" ist nicht korrekt. – Grodriguez
Oh, sicher, es ist keine formale Implikation. Die Tatsache, dass sie angeben, dass das Ende des Konstruktors vor dem Start der Finalizer-Methode auftritt, soll jedoch "Hinweise darauf" enthalten, dass dies für beliebige Methoden möglicherweise nicht zutrifft. – aioobe
@aioobe nein, das ist nur für Fälle wie den folgenden Code: 'new SomeObject()', d. H. Aufruf des Konstruktors, aber nicht Speichern der Referenz. Dann kann das Objekt sofort Müll gesammelt werden und der Finalizer kann sofort aufgerufen werden. Der Satz, auf den Sie sich beziehen, stellt nur sicher, dass der Konstruktor immer noch fertig ist, bevor der Finalizer ausgeführt wird. –