我正在将一个小的 C++ 片段翻译成 java,但我对内存排序/围栏没有 100% 的信心。这是正确的吗:
C++:
std::atomic<size_t> seq;
...
seq.store(1,std::memory_order_release);
...
seq.load(std::memory_order_acquire);
我认为它应该如何转化为 Java:
unsafe.putLong(addr,1);
unsafe.storeFence();
unsafe.getLong(addr);
unsafe.loadFence();
这是正确的路线吗? (是的,与仅使用 AtomicLong 相比,使用不安全是有原因的)
最佳答案
正确的顺序如下:
unsafe.storeFence(); // this fence has to come before the store!
unsafe.putLong(addr,1);
unsafe.getLong(addr);
unsafe.loadFence();
C++ 代码的目的通常是确保在 seq.store(1,std::memory_order_release)
之前发生的所有存储在一个线程中对 seq.load(std::memory_order_acquire);
之后的所有负载可见在另一个线程中,一旦 1 存储到 seq
本身变得可见。
为了将其传输到 Java,您必须确保在 unsafe.getLong(addr);
之前没有重新排序负载并且在 unsafe.putLong(addr,1);
之后没有商店重新订购
如果你把 storeFence
在商店后面,与任何其他商店相比,您无法保证该商店的重新订购方式。
如果您的 C++ 代码有不同的用途,答案可能会有所不同,但为此您必须展示一个示例代码来演示您要实现的目标。
关于java - 将 C++ 内存排序映射到 Java,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29285506/