Java Unsafe.storeFence() 文档有误?
Java Unsafe.storeFence() documentation wrong?
Java 8 已经在 sun.misc.Unsafe
.
添加了三个栅栏
看了他们的文档后,我感到很困惑。
所以,我在网上搜索,找到了这个 link。
根据上面的页面,我相信这些方法在实践中几乎没有增加任何内容。如果我错了请纠正我,粗略地说,loadFence()、storeFence() 和 fullFence() 分别对应于 volatile read、lazy write 和 volatile write,尽管从技术上讲这些栅栏比 volatile 变量更强。所以loadFence()是acquire fence,storeFence()是release fence,fullFence()是full fence
但是 storeFence() 的文档看起来很奇怪。
它说,
/**
* Ensures lack of reordering of stores before the fence
* with loads or stores after the fence.
*/
void storeFence();
这看起来不像是释放围栏。应该如何使用?不应该
/**
* Ensures lack of reordering of loads or stores before the fence
* with stores after the fence.
*/
void storeFence();
我假设 before 意味着更早,after 意味着更晚。
编辑
当我说这些 "fences add nothing in practice" 时,我并不是说 "we don't use them in usual development"。
我的意思是,即使没有Unsafe中的这些方法,我们也可以获得这些"fences"。如果我是正确的,实际上,读取虚拟 volatile 具有 loadFence() 的效果,写入虚拟 volatile 具有 fullFence() 和 unsafe.putOrderedXXX()(或 AtomicInteger.lazySet())的效果) 具有 storeFence() 的效果。
它们可能有细微的差别,但在当前的实现中,它们是可以互换的。 (似乎暗示了link)
这就是我所说的"they add nothing new"。
另一个编辑
这已经修复了。
见https://bugs.openjdk.java.net/browse/JDK-8038978
感谢@john-vint
I believe these methods add almost nothing in practice.
正确,他们不会在 99.9% 的应用程序中添加任何内容。只有在非常特殊的情况下才需要直接调用此方法而不是使用更高级别的构造。
volatile read, lazy write and volatile write respectively,
我读为 "volatile read, volatile write, volatile write and read" 似乎没有 lazy/ordered 写栅栏。
loadFence() is an acquire fence, and storeFence() is a release fence,
我不相信这些会转化为 acquire/release 语义。它们比那更基本。例如,这些方法中没有状态变化。 acquire/release 需要一个原子操作,例如 compareAndSet,这是另一种不安全的方法。
在 JDK9 中实际上有一个 diff。有类似问题被问及澄清:
http://hg.openjdk.java.net/jdk9/jdk9/jdk/rev/84e19392365e
/**
! * Ensures that loads before the fence will not be reordered with loads and
! * stores after the fence; a "LoadLoad plus LoadStore barrier".
! *
! * Corresponds to C11 atomic_thread_fence(memory_order_acquire)
! * (an "acquire fence").
! *
! * A pure LoadLoad fence is not provided, since the addition of LoadStore
! * is almost always desired, and most current hardware instructions that
! * provide a LoadLoad barrier also provide a LoadStore barrier for free.
* @since 1.8
*/
public native void loadFence();
/**
! * Ensures that loads and stores before the fence will not be reordered with
! * stores after the fence; a "StoreStore plus LoadStore barrier".
! *
! * Corresponds to C11 atomic_thread_fence(memory_order_release)
! * (a "release fence").
! *
! * A pure StoreStore fence is not provided, since the addition of LoadStore
! * is almost always desired, and most current hardware instructions that
! * provide a StoreStore barrier also provide a LoadStore barrier for free.
* @since 1.8
*/
public native void storeFence();
/**
! * Ensures that loads and stores before the fence will not be reordered
! * with loads and stores after the fence. Implies the effects of both
! * loadFence() and storeFence(), and in addition, the effect of a StoreLoad
! * barrier.
! *
! * Corresponds to C11 atomic_thread_fence(memory_order_seq_cst).
* @since 1.8
*/
public native void fullFence();
Java 8 已经在 sun.misc.Unsafe
.
看了他们的文档后,我感到很困惑。
所以,我在网上搜索,找到了这个 link。
根据上面的页面,我相信这些方法在实践中几乎没有增加任何内容。如果我错了请纠正我,粗略地说,loadFence()、storeFence() 和 fullFence() 分别对应于 volatile read、lazy write 和 volatile write,尽管从技术上讲这些栅栏比 volatile 变量更强。所以loadFence()是acquire fence,storeFence()是release fence,fullFence()是full fence
但是 storeFence() 的文档看起来很奇怪。
它说,
/**
* Ensures lack of reordering of stores before the fence
* with loads or stores after the fence.
*/
void storeFence();
这看起来不像是释放围栏。应该如何使用?不应该
/**
* Ensures lack of reordering of loads or stores before the fence
* with stores after the fence.
*/
void storeFence();
我假设 before 意味着更早,after 意味着更晚。
编辑
当我说这些 "fences add nothing in practice" 时,我并不是说 "we don't use them in usual development"。
我的意思是,即使没有Unsafe中的这些方法,我们也可以获得这些"fences"。如果我是正确的,实际上,读取虚拟 volatile 具有 loadFence() 的效果,写入虚拟 volatile 具有 fullFence() 和 unsafe.putOrderedXXX()(或 AtomicInteger.lazySet())的效果) 具有 storeFence() 的效果。
它们可能有细微的差别,但在当前的实现中,它们是可以互换的。 (似乎暗示了link)
这就是我所说的"they add nothing new"。
另一个编辑
这已经修复了。
见https://bugs.openjdk.java.net/browse/JDK-8038978
感谢@john-vint
I believe these methods add almost nothing in practice.
正确,他们不会在 99.9% 的应用程序中添加任何内容。只有在非常特殊的情况下才需要直接调用此方法而不是使用更高级别的构造。
volatile read, lazy write and volatile write respectively,
我读为 "volatile read, volatile write, volatile write and read" 似乎没有 lazy/ordered 写栅栏。
loadFence() is an acquire fence, and storeFence() is a release fence,
我不相信这些会转化为 acquire/release 语义。它们比那更基本。例如,这些方法中没有状态变化。 acquire/release 需要一个原子操作,例如 compareAndSet,这是另一种不安全的方法。
在 JDK9 中实际上有一个 diff。有类似问题被问及澄清:
http://hg.openjdk.java.net/jdk9/jdk9/jdk/rev/84e19392365e
/**
! * Ensures that loads before the fence will not be reordered with loads and
! * stores after the fence; a "LoadLoad plus LoadStore barrier".
! *
! * Corresponds to C11 atomic_thread_fence(memory_order_acquire)
! * (an "acquire fence").
! *
! * A pure LoadLoad fence is not provided, since the addition of LoadStore
! * is almost always desired, and most current hardware instructions that
! * provide a LoadLoad barrier also provide a LoadStore barrier for free.
* @since 1.8
*/
public native void loadFence();
/**
! * Ensures that loads and stores before the fence will not be reordered with
! * stores after the fence; a "StoreStore plus LoadStore barrier".
! *
! * Corresponds to C11 atomic_thread_fence(memory_order_release)
! * (a "release fence").
! *
! * A pure StoreStore fence is not provided, since the addition of LoadStore
! * is almost always desired, and most current hardware instructions that
! * provide a StoreStore barrier also provide a LoadStore barrier for free.
* @since 1.8
*/
public native void storeFence();
/**
! * Ensures that loads and stores before the fence will not be reordered
! * with loads and stores after the fence. Implies the effects of both
! * loadFence() and storeFence(), and in addition, the effect of a StoreLoad
! * barrier.
! *
! * Corresponds to C11 atomic_thread_fence(memory_order_seq_cst).
* @since 1.8
*/
public native void fullFence();