2010-03-14 63 views
42

(注意,這個問題不是關於CAS,它是關於「可能虛假地失敗」 Javadoc)。weakCompareAndSet如果像compareAndSet一樣實現,它會如何虛假地失敗?

AtomicInteger類這兩種方法之間的Javadoc唯一的區別是,weakCompareAndSet包含批註:「可能意外失敗」

現在,除非我的眼睛是用符咒被騙,方法都做看起來是這樣的結果:

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); 
} 

所以我意識到,「可能」並不意味着「必須」但當時爲什麼不難道我們都開始添加這我們的代碼庫:

public void doIt() { 
    a(); 
} 

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

我與weakCompareAndSet()出現做相同compareAndSet()真的感到困惑的是‘可能會意外失敗’而另一個則不行。

顯然,「弱」和「虛假失敗」與「發生之前」排序有關,但我仍然非常困惑這兩個AtomicInteger(和AtomicLong等)方法:因爲顯然他們撥打完全相同的unsafe.compareAndSwapInt方法

我感到特別困惑在AtomicInteger得到了Java內存模型變化後Java 1.5中引入的,所以(所以它顯然不是東西,可以「在1.4意外失敗」,但其行爲改爲「應不會在1.5「中虛假地失敗)。

+0

好問題智者 – 2010-03-14 18:39:54

+0

確實很奇怪。這可能是API未來打擊,但這是一個奇怪的方式去做。似乎所有'AtomicXYZ'類在'compareAndSet'和'weakCompareAndSet'中做了同樣的事情,所以它不像是爲了實現一致性。 – skaffman 2010-03-14 18:43:27

+0

參見http://stackoverflow.com/questions/4183202/java-compare-and-swap-semantics-and-performance – assylias 2013-05-13 21:56:44

回答

19

有實現和規範之間的區別...

雖然特定的實現有可能不提供不同的實現多點,未來的實現也許在不同的硬件可能需要。這種方法是否在API中佔有重要位置是值得商榷的。

另外weak方法沒有發生在排序定義之前。非weak版本的行爲類似於volatile字段。

+0

@Tom Hawtin - tackline:+1 ...你知道任何硬件上的JVM實現(Sun或非Sun)嗎? – SyntaxT3rr0r 2010-03-14 18:55:12

+0

不,我甚至不知道是否有任何主流硬件可以改變它。我相信爲了獲得弱的不穩定行爲,你必須爲所有事情做到這一點。當然,事情的另一方面是編譯器,它可能會將數據留在寄存器中,否則會被刷新。 – 2010-03-14 19:21:53

+0

「另外弱方法沒有發生 - 在排序定義之前,非弱版本的行爲就像是volatile字段。」如果是這樣,java.util.concurrent.atomic中的這種方法的意義何在?包? – Rollerball 2013-06-03 16:40:05

1

只是打了一下,如果你的問題是

如何weakDoIt意外失敗如果實現了完全一樣doIt方法?

這裏是答案!

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!"); 
} 
相關問題