不支持 CAS 操作的处理器上的 compareAndSet

Posted

技术标签:

【中文标题】不支持 CAS 操作的处理器上的 compareAndSet【英文标题】:compareAndSet on processors that does not support CAS operation 【发布时间】:2017-10-18 19:39:45 【问题描述】:

今天我在一次采访中被问到下一个问题:“如果您在具有不支持 CAS 操作的处理器的机器上调用 AtomicLong 中的 compareAndSet 方法,会发生什么”。

能否请您帮助我解决这个问题,并在可能的情况下提供一些指向全面描述的链接?

【问题讨论】:

【参考方案1】:

来自Java Concurrency in Practice 15.2.3 JVM 中的 CAS 支持

在支持 CAS 的平台上,运行时将它们内联到适当的机器指令中;在最坏的情况下, 如果类似 CAS 的指令不可用,则 JVM 使用自旋锁。

【讨论】:

【参考方案2】:

查看AtomicLong 类源代码。我们可以找到这个:

/**
 * Records whether the underlying JVM supports lockless
 * compareAndSet for longs. While the intrinsic compareAndSetLong
 * method works in either case, some constructions should be
 * handled at Java level to avoid locking user-visible locks.
 */
static final boolean VM_SUPPORTS_LONG_CAS = VMSupportsCS8();

这意味着它可以在任何情况下工作。根据实现,JVM 可能会尝试获取锁,如果无法再次尝试(轮询)。

从评论来看,JVM 使用的是std::atomic::compare_and_exchange_strong

/**
 * ...
 * <p>This operation has memory semantics of a @code volatile read
 * and write.  Corresponds to C11 atomic_compare_exchange_strong.
 * ...
 */
@ForceInline
public final boolean compareAndSwapInt(Object o, long offset,
                                       int expected,
                                       int x) 
    return theInternalUnsafe.compareAndSetInt(o, offset, expected, x);

【讨论】:

首先非常感谢您的回复。但我对支持 CAS 的处理器和不支持 CAS 的处理器的行为的确切差异感兴趣。似乎在不支持 CAS 的处理器的情况下,为 compareAndSet 方法完成了某种其他类型的同步。我需要更多细节。 不幸的是,我不知道确切的区别,除了定期轮询 JVM 锁定的一些互斥锁:)。它没有指定,并且可能因 JVM 不同而异。也许非CAS处理器工作原理上的C11方法std::atomic::compare_and_exchange_strong会有所帮助。

以上是关于不支持 CAS 操作的处理器上的 compareAndSet的主要内容,如果未能解决你的问题,请参考以下文章

聊聊并发——CAS算法

CAS解析

CAS讲解

java中的CAS

Java高性能编程之CAS与ABA及解决方法

CAS和AQS