如何在Java的Atomic *类中实现lazySet?

在这个关于Disruptor (一个并发框架)的video中 ,提到了Java的Atomic *类(例如AtomicLong)的lazySet方法。 根据文档 ,此方法“最终设置为给定值”。

有没有人知道实现这个的基本机制是什么(特别是在Windows上的x86,如果这是相关的)。 它不能是InterlockedExchange() ,因为这会设置值并确保在返回之前刷新缓存行,如果我没有弄错的话。

这基本上调用unsafe.putOrderedLong()这是一个本机函数。 基于有序 (懒惰)与易失性 (立即)之间的不安全区分。 我几乎可以肯定(懒惰)版本只是解析为storestore而volatile需要更昂贵的loadstore 。 这样可以保留线程语义(对于设置线程)而不会停止所有其他核心。 最终读者将获得新的价值。

[编辑:那说(这是推测性的),我确信懒惰的商店使用完全不稳定的“更轻”的内存防护 – 如果平台提供的话。 例如,我没有看到你在C#中不能做同样的事情,比如x86]

像这样的东西的典型用法是计数器(比如队列深度)。 如果你在每次迭代中遇到一个volatile,它将不会是“高性能”,因为你在每次迭代中都会产生缓存一致性的全部成本。 如果您的并发交互允许“模糊”读数然后您(通过内存进行交互),那么这种技术可以降低维护整个系统状态的成本(在可接受的误差范围内,例如您的队列深度读数有点偏差。)

[ps /编辑: Distruptor设计师对击剑的讨论 。]

在Bug 6275329中找到了对该实现的描述:

语义是保证写入不会与任何先前的写入一起重新排序,但可以与后续操作重新排序(或者等效地,可能对其他线程不可见),直到发生一些其他易失性写入或同步动作)。

对于那些喜欢在常见多处理器上的机器级障碍方面考虑这些操作的人来说,lazySet提供了一个先前的商店存储障碍 (在当前平台上是无操作或非常便宜), 但没有存储负载障碍 (这通常是volatile写入的昂贵部分)