2010-03-14 2 views
42

(beachten Sie, dass diese Frage nicht über CAS ist, es geht um die "Kann fälschlicherweise fehlschlagen" Javadoc).Wie kann weakCompareAndSet fälschlicherweise fehlschlagen, wenn es genau wie compareAndSet implementiert wird?

Der einzige Unterschied in der Javadoc zwischen diesen beiden Methoden aus der AtomicInteger Klasse ist, dass der weakCompareAndSet den Kommentar enthält: „Darf spuriously fail“. Jetzt

es sei denn, meine Augen von einigen Zauber betrogen werden, die beide Methode suchen, um genau tun das gleiche:

public final boolean compareAndSet(int expect, int update) { 
    return unsafe.compareAndSwapInt(this, valueOffset, expect, update); 
} 

/* ... 
* May fail spuriously. 
*/ 
public final boolean weakCompareAndSet(int expect, int update) { 
    return unsafe.compareAndSwapInt(this, valueOffset, expect, update); 
} 

So merke ich, dass „Mai“ bedeutet nicht „Muss“, aber dann, warum don ‚t wir alle, diese zu unserem Code-Basis zu starten:

public void doIt() { 
    a(); 
} 

/** 
* May fail spuriously 
*/ 
public void weakDoIt() { 
    a(); 
} 

ich bin wirklich verwirrt mit diesem weakCompareAndSet(), die die gleiche wie die compareAndSet() noch zu tun scheint, dass‚spuriously fehlschlagen‘ während der andere nicht kann.

Anscheinend sind die "schwache" und die "falsche Fehler" in gewisser Weise verwandt mit "passiert vor" Bestellung, aber ich bin immer noch sehr verwirrt durch diese beiden AtomicInteger (und AtomicLong etc.) Methoden: weil sie anscheinend rufen Sie genau das gleiche unsafe.compareAndSwapInt Methode.

Ich bin besonders verwirrt, dass AtomicInteger in Java 1.5 eingeführt wurde, so dass nach dem Java-Speichermodell ändern (so ist es offensichtlich nicht etwas, das „fail in 1,4 spuriously“ konnte aber dessen Verhalten zu geändert „wird nicht versehentlich in 1,5 ") fehlschlagen.

+0

Gute Frage Wiz –

+0

Weird in der Tat. Es könnte eine zukunftssichere API sein, aber das ist ein seltsamer Weg. Es scheint, dass alle 'AtomicXYZ'-Klassen dasselbe in' compareAndSet' und 'weakCompareAndSet' tun, also ist es auch nicht so, als ob es für Konsistenz zwischen Implementierungen ist. – skaffman

+0

Siehe auch http://stackoverflow.com/questions/4183202/java-compare-and-swap-semantics-and-performance – assylias

Antwort

19

Es gibt einen Unterschied zwischen Implementierung und Spezifikation ...

Während auf einer bestimmten Implementierung es nicht viel Sinn sein kann verschiedene Implementierungen der Bereitstellung, zukünftige Implementierungen vielleicht auf verschiedenen Hardware können wollen. Ob diese Methode ihr Gewicht in der API trägt, ist fraglich.

Auch die weak Methoden haben keine passiert vor Bestellung definiert. Die nicht weak Versionen verhalten sich wie volatile Felder.

+0

@Tom Hawtin - Tackline: +1 ... Kennen Sie irgendeine JVM-Implementierung (Sun oder Nicht-Sun) auf irgendeiner Hardware, wo es unterschiedliche Implementierung für solche Methoden gibt? – SyntaxT3rr0r

+0

Nein. Ich weiß nicht einmal, ob es Mainstream-Hardware gibt, wo es einen Unterschied machen würde. Ich glaube, um das schwache flüchtige Verhalten zu bekommen, muss man es für alles tun. Die andere Seite der Dinge ist natürlich der Compiler, der Daten in Registern hinterlassen könnte, die sonst gelöscht würden. –

+0

"Auch die schwachen Methoden haben keine Vorkommnisse vor der Bestellung definiert. Die nicht-schwachen Versionen verhalten sich wie flüchtige Felder." Wenn ja, was ist der Sinn einer solchen Methode in java.util.concurrent.atomic; Paket? – Rollerball

1

nur ein bisschen zu spielen, wenn Ihre Frage war

Wie kann weakDoIt spuriously fehlschlagen, wenn es genau wie doIt umgesetzt wird?

hier ist die Antwort!

public void doIt() { 
    a(); 
} 

/** 
* May fail spuriously 
*/ 
public void weakDoIt() { 
    a(); 
} 

void a(){ 
    if(Thread.currentThread().getStackTrace()[2].toString().contains("weakDoIt")) 
     System.out.println("I will fail spuriously!"); 
    else System.out.println("I won't fail spuriously!"); 
}