假设一些“N”个线程正在尝试CAS一个AtomicInteger变量,是否保证CAS必须成功完成一个线程?
是否有可能所有“N”线程都尝试失败?
答案 0 :(得分:4)
compareAndSet
旨在由硬件实现,因此行为将取决于您正在运行的特定硬件。来自java.util.concurrent.atomic:
如果当前持有expectedValue,则此方法(在不同类的参数类型中有所不同)以原子方式将变量设置为updateValue,成功时报告为true。此包中的类还包含获取和无条件设置值的方法,以及下面描述的弱条件原子更新操作weakCompareAndSet。
这些方法的规范使实现能够采用当代处理器上可用的高效机器级原子指令。但是在某些平台上,支持可能需要某种形式的内部锁定。因此,不严格保证方法是非阻塞的 - 线程可能在执行操作之前暂时阻塞。
假设典型硬件,第一个到达底层硬件指令的线程将执行原子CAS(假设它具有正确的初始值),并且所有其他线程都将失败。
如果底层硬件允许所有竞争线程失败,那么Java API中似乎没有任何需要不同行为的东西。但是,对于所有线程可能失败的CAS可能导致实时锁定情况和非确定性行为,因此任何实现CAS的硬件都可能保证一个线程将成功。
答案 1 :(得分:2)
也许值得一提的是,您在concurrency interest list上提出了问题并获得了以下answer:
是的,AtomicX.compareAndSet保证。
真的,首先是“强”和“弱”CAS之间的区别 一个人不能虚假地失败,第二个可以。 AtomicX.compareAndSet 是“强大的”CAS。 AtomicX.weakCompareAndSet是“弱”的例子 CAS,并且可以在没有特殊原因的情况下对所有线程进行虚假的失败。
在只有LL/SC而不是直接提供强CAS的硬件上,强CAS的内部实现需要重试循环。
因此,在Java级别,强大的CAS仍然很强大,但从活锁/争用/硬件级别来看,它实际上正在重试。