English 中文(简体)
AtomicInteger中的“虚假故障”是指什么?
原标题:
  • 时间:2008-12-10 07:44:32
  •  标签:

Java AtomicInteger类有一个方法 -

boolean weakCompareAndSet(int expect,int update)

它的文档说:

可能假警。

这里的“failing spuriously”是什么意思?

问题回答

虚假地:没有明显的原因

根据 atomic 包的javadoc:

原子类也支持weakCompareAndSet方法,其适用范围有限。

在某些平台上,在正常情况下,弱版本可能比compareAndSet更有效,但是它的不同之处在于,任何调用弱比较并设置方法的返回值都可能出现虚假的false(也就是说,没有明显的原因)。

A false return means only that the operation may be retried if desired, relying on the guarantee that repeated invocation when the variable holds expectedValue and no other thread is also attempting to set the variable will eventually succeed.
(Such spurious failures may for example be due to memory contention effects that are unrelated to whether the expected and current values are equal.)

此外,weakCompareAndSet并不提供通常用于同步控制的排序保证。


根据这个主题,它不是因为“硬件/操作系统”,而是因为弱CompareAndSet所使用的底层算法。

如果当前值==期望值,则weakCompareAndSet原子性地将值设置为给定的更新值。可能会偶尔失败。

与compareAndSet()和AtomicX上的其他操作不同,weakCompareAndSet()操作不创建任何先于发生的排序。

因此,仅仅因为一个线程看到了由weakCompareAndSet引起的AtomicX的更新,并不意味着它与在weakCompareAndSet()之前发生的操作进行了适当的同步。

您可能不想使用这种方法,而是应该只使用compareAndSet;因为很少有情况下weakCompareAndSet比compareAndSet更快,并且在一些情况下,尝试通过使用weakCompareAndSet而不是compareAndSet来优化您的代码将在您的代码中引入微妙且难以重现的同步错误。


关于 先于关系排序 的说明:

Java内存模型(JMM)定义了在哪些条件下,一个线程读取一个变量时保证能看到另一个线程中写的结果。

JMM 定义了一个程序操作的排序,称为 happens-before。

现场发生顺序跨线程仅通过同步在共同锁定或访问共同的易失性变量创建。

在缺乏发生前顺序的情况下,Java平台有很大的自由度来延迟或更改一个线程中的写入所变为的可见性,以便另一个变量的读取。

这意味着它可能返回false(并且不会设置新值),即使它当前包含了预期的值。

In other words, the method may do nothing and return false for no apparent reason...
There are CPU architectures where this may have a performance advantage over a strong CompareAndSet().


为什么会发生类似这样的事情,可以提供一些更具体的细节。

一些架构(例如新的ARM)使用负载链接(LL)/存储条件(SC)指令集来实现CAS操作。LL指令将内存位置中的值加载并在某个地方记住地址。SC指令会将值存储到该内存位置,如果记住地址处的值未被修改。硬件可能认为该位置已经被修改,即使它似乎没有被修改的原因有很多可能的原因(而这些原因可能因CPU架构而异)。

  1. the location may have been written with the same value
  2. the resolution of the addresses watched might not be exactly the one memory location of interest (think cache lines). A write to another location that s close-by may cause the hardware to flag the address in question as dirty
  3. a number of other reasons that may cause the CPU to lose the saved state of the LL instruction - context switches, cache flushes, or page table changes maybe.

弱比较交换的一个很好的使用案例是性能计数器——不需要排序,更新频率高(所以在弱有序系统上排序会影响性能),但在高负载下不会丢失计数(紧密竞争的性能计数器可以丢失 99% 的所有计数,基本上使计数器相对于未竞争计数器的值变为随机的)。





相关问题
热门标签