7

假设一些“N”个线程正在尝试对一个 AtomicInteger 变量进行 CAS 处理,是否保证 CAS 必须为一个线程成功?

是否有可能所有“N”个线程都尝试失败?

4

2 回答 2

4

compareAndSet旨在由硬件实现,因此行为将取决于您正在运行的特定硬件。来自 java.util.concurrent.atomic:

此方法(不同类的参数类型不同)自动将变量设置为 updateValue,如果它当前持有预期值,成功时报告 true。这个包中的类还包含获取和无条件设置值的方法,以及下面描述的较弱的条件原子更新操作weakCompareAndSet。

这些方法的规范使实现能够使用现代处理器上可用的有效机器级原子指令。但是在某些平台上,支持可能需要某种形式的内部锁定。因此,这些方法不能严格保证是非阻塞的——线程可能会在执行操作之前暂时阻塞。

假设典型的硬件,到达底层硬件指令的第一个线程将执行原子 CAS(假设它具有正确的初始值)并且所有其他线程都将失败。

如果底层硬件允许所有竞争线程失败,那么 Java API 中似乎没有任何东西需要不同的行为。然而,一个可能对所有线程都失败的 CAS 可能会导致活锁情况和非确定性行为,因此任何实现 CAS 的硬件都可能保证一个线程会成功。

于 2013-01-22T07:49:07.333 回答
2

也许值得一提的是,您在并发兴趣列表上提出了问题并得到了以下答案

是的,AtomicX.compareAndSet 可以保证。

确实,CAS有“强”和“弱”之分,第一个不能假失败,第二个可以。AtomicX.compareAndSet 是“强”的 CAS。AtomicX.weakCompareAndSet 是“弱” CAS 的示例,并且可以在没有特定原因的情况下对所有线程虚假地失败。

在只有LL/SC而不是直接提供强 CAS 的硬件上,强 CAS 的内部实现需要一个重试循环。

因此,在 Java 级别,强大的 CAS 仍然很强大,但从活锁/争用/硬件级别来看,它实际上是在重试。

于 2013-02-01T09:29:29.907 回答