2015-11-13 13 views
6

Für die folgende vereinfachte Klasse:Java Memory Visibility In Konstrukteurs

public class MutableInteger { 
    private int value; 
    public MutableInteger(int initial) { 
     synchronized(this) { // is this necessary for memory visibility? 
      this.value = initial; 
     } 
    } 
    public synchronized int get() { 
     return this.value; 
    } 
    public synchronized void increment() { 
     this.value++; 
    } 
    ... 
} 

Ich denke, die allgemeine Frage für änderbare Variablen ist durch die Synchronisation bewacht ist es notwendig, zu synchronisieren, wenn im Konstruktor den Anfangswert?

+0

Was wollen Sie erreichen? – biziclop

+1

Ich sehe keine Möglichkeit, wie zwei Threads in der gleichen Instanz sein könnten, während es gebaut wird, also würde ich nein sagen. Wenn der Wert vielleicht statisch wäre, müssten Sie aber das Klassenobjekt und nicht die Referenz synchronisieren. – Pace

+1

@biziclop Ich bin nur sicher, dass alle meinen Code zu machen versuche, ist richtig in Bezug auf Thread-Sicherheit und um besser auf das Java-Speichermodell zu verstehen. – nikdeapen

Antwort

3

Sie haben Recht, ohne den synchronized Block im Konstruktor gibt es keine Sichtbarkeitsgarantie für nicht endgültige Felder, wie in this example zu sehen ist. In der Praxis würde ich lieber volatile Felder oder Atomic* Klassen in Situationen wie diesem verwenden.

Update: Es ist auch wichtig zu erwähnen, dass für Ihr Programm, um correctly synchronized zu sein (wie durch die JLS definiert ist), müssen Sie den Verweis auf das Objekt in einer sicheren Weise veröffentlichen. Das genannte Beispiel macht das nicht, weshalb Sie in nicht endgültigen Feldern möglicherweise den falschen Wert sehen. Aber wenn Sie den Objektverweis korrekt veröffentlichen (dh, indem sie ein final Feld eines anderes Objekts zuweisen, oder durch die Schaffung vor Thread.start() Aufruf) ist gewährleistet, dass Ihr Objekt zumindest sehen, wie up-to-date als die Zeit der Veröffentlichung, daher den synchronized Block im Konstruktor unnötig machen.

+0

Danke, das ist, was ich gesucht habe. Ich würde in diesem Fall definitiv die atomaren Klassen verwenden, aber das funktioniert nur in einfachen Fällen. – nikdeapen

+0

Wenn ich das in der Java-Spezifikation nicht mit meinen eigenen Augen sehen würde, würde ich dich als Lügner bezeichnen. OK, Zeit, darüber auf The Daily WTF zu schreiben. – Powerlord

+0

@Powerlord Ich denke, die meisten modernen VMs schaffen eine Speicherbarriere am Ende eines Konstruktors, aber nicht garantiert, sieht in der Tat seltsam aus. Eine Regel für einen Konstruktor und eine andere für andere Schreibvorgänge zu haben, wäre jedoch wahrscheinlich noch verwirrender. – biziclop