2015-06-02 21 views
11

Java 8 hat sun.misc.Unsafe drei Zäune hinzugefügt.Java Unsafe.storeFence() Dokumentation falsch?

Ich fühle mich verwirrt, nachdem ich ihre Dokumentation gelesen habe.

Also suchte ich im Internet, und fand diese link.

Laut der obigen Seite, glaube ich, diese Methoden hinzufügen fast nichts in der Praxis. Korrigieren Sie mich, wenn ich falsch liege, Grob gesagt, loadFence(), storeFence() und fullFence() entsprechen volatilem Lesen, Lazy Write bzw. flüchtigem Schreiben, obwohl technisch diese Zäune stärker sind als flüchtige Variablen. So ist loadFence() ein acquire fence, und storeFence() ist ein Freisetzungszaun und fullFence() ist ein full fence.

Aber dann sieht die Dokumentation für storeFence() seltsam aus.

Es sagt,

/** 
* Ensures lack of reordering of stores before the fence 
* with loads or stores after the fence. 
*/ 
void storeFence(); 

Das ist nicht wie ein Release Zaun aussieht. Wie soll es verwendet werden? Sollte nicht es

/** 
* Ensures lack of reordering of loads or stores before the fence 
* with stores after the fence. 
*/ 
void storeFence(); 

Ich gehe davon aus vor bedeutet früher und nach bedeutet später.

EDIT

meine ich nicht „wir sie nicht in üblichen Entwicklung verwenden“, wenn ich sagen, dass diese „Zäune nichts in der Praxis hinzufügen“.

Ich meine, auch ohne diese Methoden in Unsafe, können wir diese "Zäune" ​​bekommen. Wenn ich in der Praxis richtig bin, hat das Lesen eines Dummy-Volatile den Effekt von loadFence(), und das Schreiben eines Dummy-Volatile hat den Effekt von fullFence(), und unsafe.putOrderedXXX() (oder AtomicInteger.lazySet()) hat den Effekt von storeFence().

Sie können einen kleinen Unterschied haben, aber in der aktuellen Implementierung sind sie austauschbar. (Scheint durch den Link impliziert)

Das ist, was ich mit "sie fügen nichts Neues" bedeuten.

ANOTHER EDIT

Diese bereits festgelegt ist.

Siehe https://bugs.openjdk.java.net/browse/JDK-8038978

Thanks @ john-Vint

+0

Eine [Implementierung link] (http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/file/50fdb38839eb/src /share/vm/opto/library_call.cpp#l3102), was hilfreich sein könnte. –

Antwort

6

Es gibt tatsächlich einen Unterschied für dieses in JDK9. Es gab ähnliche Fragen, die gestellt wurden und geklärt:

http://hg.openjdk.java.net/jdk9/jdk9/jdk/rev/84e19392365e

 /** 
!  * Ensures that loads before the fence will not be reordered with loads and 
!  * stores after the fence; a "LoadLoad plus LoadStore barrier". 
!  * 
!  * Corresponds to C11 atomic_thread_fence(memory_order_acquire) 
!  * (an "acquire fence"). 
!  * 
!  * A pure LoadLoad fence is not provided, since the addition of LoadStore 
!  * is almost always desired, and most current hardware instructions that 
!  * provide a LoadLoad barrier also provide a LoadStore barrier for free. 
     * @since 1.8 
     */ 
     public native void loadFence(); 

     /** 
!  * Ensures that loads and stores before the fence will not be reordered with 
!  * stores after the fence; a "StoreStore plus LoadStore barrier". 
!  * 
!  * Corresponds to C11 atomic_thread_fence(memory_order_release) 
!  * (a "release fence"). 
!  * 
!  * A pure StoreStore fence is not provided, since the addition of LoadStore 
!  * is almost always desired, and most current hardware instructions that 
!  * provide a StoreStore barrier also provide a LoadStore barrier for free. 
     * @since 1.8 
     */ 
     public native void storeFence(); 

     /** 
!  * Ensures that loads and stores before the fence will not be reordered 
!  * with loads and stores after the fence. Implies the effects of both 
!  * loadFence() and storeFence(), and in addition, the effect of a StoreLoad 
!  * barrier. 
!  * 
!  * Corresponds to C11 atomic_thread_fence(memory_order_seq_cst). 
     * @since 1.8 
     */ 
     public native void fullFence(); 
+1

So ist es schon geklärt. Ich bin ein wenig überrascht, dass sie sich die Mühe machen, so viele Wörter hinzuzufügen, vorausgesetzt, dass Java 9 interne APIs unbrauchbar machen soll. – ntysdd

+0

Verhindern diese Zäune nur das Umordnen von Lese- und Schreibvorgängen oder leeren sie auch die Lade-/Speicherpuffer? – CaptainHastings

+0

Sie werden hauptsächlich zum Neuanordnen verwendet, und die JMM/CPU muss die Puffer nicht leeren. Wenn Sie beispielsweise vor und nach einem Schreibvorgang einen 'fullFence'-Wert angeben, während vor und nach dem Lesen der geschriebenen Variablen ein 'loadFence'-Wert hinzugefügt wird, können Sie weiterhin veraltete Lesevorgänge beobachten. –

0

Ich glaube, dass diese Methoden in der Praxis so gut wie nichts hinzuzufügen.

Richtig, sie würden in 99,9% der Anwendungen nichts hinzufügen. Es ist nur in sehr speziellen Fällen notwendig, dass Sie diese Methode direkt aufrufen müssen, anstatt ein höheres Konstrukt zu verwenden.

flüchtiger Lese-, Schreib- und faul flüchtiger Schreib- bzw.

Ich lese es als „flüchtig lesen, flüchtigen Schreib, flüchtige Schreib- und Lese“ Es scheint nicht ein fauler/geordnete Schreib zu sein Zaun.

loadFence() ist ein acquire Zaun und storeFence() ist ein Trennzaun,

Ich glaube nicht, diese bedeutet eine acquire/release Semantik. Sie sind mehr grundlegend als das. Bei diesen Methoden gibt es beispielsweise keine Zustandsänderung. acquire/release erfordert eine atomare Operation wie compareAndSet, die eine andere unsafe-Methode ist.

+0

ich meine so etwas wie "AtomicInteger.lazySet()", wenn ich sage, faul schreiben – ntysdd

+0

Ich verstehe nicht, warum Sie sagen, sie übersetzen nicht zu erwerben/Semantik zu lösen. Das Dokument für loadFence() sagt "Gewährleistet fehlende Neuordnung der Lasten vor dem Zaun mit Lasten oder speichert nach dem Zaun.", Das klingt fast die Definition einer Barriere zu erwerben. – ntysdd

+0

@ntysdd was meinst du mit "Barriere erwerben"? Diese lesen oder schreiben nicht, also was erwirbt oder gibt er frei? Ich nehme an, Sie sprechen nicht über Semaphore.acquire/release. –