2012-04-12 13 views
9

Gibt es einen Grund, volatile und synchronisierte in diesem Code zusammen zu verwenden?Flüchtig mit synchronisiert zusammen

public class Helper { 
    private volatile int n; 
    private final Object lock = new Object(); 
    public Helper(int n) { 
    this.n = n; 
    } 

    public void setN(int value) { 
    synchronized (lock) { 
     n = value; 
    } 
    } 
} 

Klassenhelfer muss fadensicher sein. Ich habe dieses Beispiel aus dem Buch "Java Concurrency Guidelines", aber es ist immer noch nicht klar: Was ist der Grund für die Verwendung von volatilen und synchronisierten in diesem Beispiel zusammen?

+1

Worüber genau sprechen Sie? Ich würde dem Buch Java Concurrency in Practice (http://jcip.net/) dringend raten, Java-Parallelität zu lernen. –

+0

Ich habe dieses Buch hier gefunden (Seite 167) http://www.sei.cmu.edu/reports/10tr015.pdf Alles in diesem Buch ist ziemlich klar, außer in diesem Fall nur –

+0

Verwenden Sie AtomicInteger. – khachik

Antwort

7

Der Zweck dieses Beispiel darauf hin, dass syncronized ohne volatile in diesem Fall gegeben nicht genug, ist die Tatsache, dass das Objekt unsafely veröffentlicht werden kann (dh ohne volatile in Foo):

Wenn der Helfer Feld in der Foo-Klasse wird nicht als flüchtig deklariert, das n-Feld sollte als flüchtig deklariert werden, so dass eine Vor-Vor-Beziehung zwischen der Initialisierung von n und dem Schreiben von Helper in das Hilfsfeld hergestellt wird. Dies entspricht der Richtlinie "VNA06-J. Gehen Sie nicht davon aus, dass die Deklaration eines Objektreferenzfehlers die Sichtbarkeit seiner Member garantiert "auf Seite 36. Dies ist nur erforderlich, wenn dem Aufrufer (Klasse Foo) nicht gestattet werden kann, Helpervolatile zu deklarieren.

Das ist richtig, aber sie wählten ein schlechtes Beispiel, es zu demonstrieren, weil volatile ohne syncrhonization in diesem Fall genug.

0

Ich denke, dass die flüchtigen verwendet, da ‚n‘ im Konstruktor gesetzt

+0

Ja, aber welchen Grund, in setN Methode synchronisiert zu verwenden? –

+0

Oh wirklich? Ich weiß nicht, wie man den Konstruktor desselben Objekts aus 2 oder mehr Threads aufruft, oder? – hsestupin

+0

Ich weiß es auch nicht) Meine Frage war, warum Synchronisation in setN Methode benötigt. Wenn die Variable n flüchtig ist, kann Setter ohne zusätzliche Synchronisation sein. Oder nicht? –

1

Es ist nicht notwendig, den synchronisierten Block rund um die Wertänderung zu setzen; seit Java 5 wird dies für volatile Variablen "automatisch" gemacht. Ich denke, dass es vor Java 5 nicht unbedingt der Fall war.

Verwandte Themen