2010-03-14 68 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!"); 
} 
相关问题