SubmissionPublisher
(OpenJDK 10源代码, Javadoc)类的实现时,我发现了一些之前不知道的VarHandle
API调用:
fullFence
、acquireFence
、releaseFence
、loadLoadFence
和storeStoreFence
。经过一些研究,特别是关于内存屏障/栅栏的概念(我之前听说过它们,但从未使用过,因此对它们的语义非常陌生),我认为我对它们的基本用途有了一定的了解。尽管如此,由于我的问题可能来自误解,我想确保我首先就理解正确了。
记忆屏障是有关读写操作的重新排序限制。
根据它们是否对读或写设置约束,可以将内存屏障分为两大类:单向和双向内存屏障。 C ++支持各种内存屏障, 但这些与
VarHandle
提供的内存屏障不匹配。然而,在VarHandle
中可用的一些内存屏障提供了与其相应的C ++内存屏障兼容的排序效果。
#fullFence
与atomic_thread_fence(memory_order_seq_cst)
兼容#acquireFence
与atomic_thread_fence(memory_order_acquire)
兼容#releaseFence
与atomic_thread_fence(memory_order_release)
兼容#loadLoadFence
和#storeStoreFence
没有相应的C++部分
我的假设是否正确?如果是,我的问题如下:
VarHandle
中可用的内存屏障是否会导致任何类型的内存同步?无论它们是否导致内存同步,Java 中重新排序约束可能有哪些用途?当涉及到 volatile 字段、锁或类似
#compareAndSet
的VarHandle
操作时,Java 内存模型已经提供了一些非常强的排序保证。
以BufferedSubscription
为例,这是SubmissionPublisher
的一个内部类(上面链接的源代码),在growAndAdd
函数中建立了一个完整的屏障在第1079行。然而,我不确定这是用来做什么的。
plain -> opaque -> release/acquire -> volatile (sequential consistency)
。 - Eugene