2016-07-17 8 views
1

Die "Standard" Code of Copy on Write wie folgt aussieht:Verwendung von flüchtigem Feld in Copy-On-Write

... 
private volatile SomeClass object; 

private ReentrantLock lock = new ReentrantLock(); 

public change (...) { 
    lock.lock(); //set lock on write 
    try { 
     SomeClass newObject = new SomeClass(); 
     //do something with new object 
     ... 
     //set new object 
     object = newObject; 
    } finally { 
     lock.unlock(); //release lock 
    } 
} 

public Object getSomeField() { 
    SomeClass obj = object; 
    return obj.getSomeField(); 
} 

die Frage: Warum das Feld, die Bezug auf "geschützt auf write" Objekt hält flüchtig? (Siehe z. B. Implementierung von CopyOnWriteArrayList). Soweit ich weiß, ist die Objektreferenzzuweisungsoperation atomar, , also sieht es so aus, als ob in volatilem Modifizierer keine Notwendigkeit besteht. Liege ich hier falsch?

+1

Dies ist erforderlich, um andere Threads sichtbar zu machen. Ohne 'volatile' ist die Referenzzuweisung möglicherweise nur für den Thread sichtbar, der die Änderung vorgenommen hat. Sie würden es nicht benötigen, wenn die Methode unter der gleichen Sperre ausgeführt wird, mit der das Feld geändert wird. –

+0

Danke! Dies ist der Aspekt, den ich nicht berücksichtigt habe –

Antwort

2

Soweit ich die Objektreferenz Zuweisungsoperation wissen, ist Atom

Ja, aber volatile modifier ist nicht über die atomare Zuordnung, es geht um diesen Wert dieser Variablen ist für alle Threads das gleiche wäre, dass lies diese Variable.

Es geht eigentlich um atomaren Variablenzugriff, nicht um atomare Variablenzuordnung.

1

Von "Atomic Access" in the Java Tutorials (Hervorhebung von mir):

Atomic Aktionen können nicht verschachtelt werden, so können sie ohne Angst vor Faden Interferenz verwendet werden. Dies beseitigt jedoch nicht die Notwendigkeit, atomare Aktionen zu synchronisieren, da Speicherkonsistenzfehler weiterhin möglich sind. Die Verwendung von flüchtigen Variablen reduziert das Risiko von Speicherkonsistenzfehlern, da jedes Schreiben in eine flüchtige Variable eine Vorkommnis-vor-Beziehung mit nachfolgenden Lesevorgängen derselben Variablen festlegt. Dies bedeutet, dass Änderungen an einer flüchtigen Variablen immer für andere Threads sichtbar sind.