2015-06-02 3 views
11

Java 8 добавила три забора до sun.misc.Unsafe.Неверная ошибка Java Unsafe.storeFence()?

Я чувствую себя смущенным после того, как прочитал их документацию.

Итак, я искал в Интернете и нашел это link.

Согласно приведенной выше странице, я считаю, что эти методы практически не добавляют на практике. Поправьте меня, если я ошибаюсь, грубо говоря, loadFence(), storeFence() и fullFence() соответствуют волатильному чтению, ленивой записи и volatile write соответственно, хотя технически эти заграждения сильнее, чем изменчивые переменные. Таким образом loadFence() - это забор, а storeFence() - это забор, а fullFence() - полный забор.

Но тогда документация для 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(); 

Я полагаю перед тем означает, ранее и после означает позже.

EDIT

Я не имею в виду «мы не используем их в обычном развитии», когда я говорю эти «заборы ничего не добавляют на практике».

Я имею в виду, что даже без этих методов в Unsafe мы можем получить эти «заборы». Если я прав, на практике чтение фиктивной изменчивости имеет эффект loadFence(), и запись фиктивной изменчивости имеет эффект fullFence(), а эффект unsafe.putOrderedXXX() (или AtomicInteger.lazySet()) имеет эффект магазинаFence().

У них может быть тонкая разница, но в текущей реализации они могут быть обменными. (Кажется, подразумевается ссылкой)

Вот что я подразумеваю под словом «они ничего не добавляют».

ДРУГОЙ EDIT

Это уже исправлено.

См https://bugs.openjdk.java.net/browse/JDK-8038978

Спасибо @ джон-Vint

+0

[ссылка реализации] (http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/file/50fdb38839eb/src /share/vm/opto/library_call.cpp#l3102), которые могут быть полезны. –

ответ

6

Для этого в JDK9 существует различие. Были подобные вопросы, которые были заданы и осветленные:

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(); 
+1

Так что уже выяснено. Я немного удивлен, что они потрудились добавить столько слов, если Java 9 предположительно сделает внутренние API непригодными. – ntysdd

+0

Выполняют ли эти ограждения только переупорядочение чтения и записи или же они также сбрасывают буферы загрузки/хранения? – CaptainHastings

+0

Они используются в основном для переупорядочения, а JMM/CPU не нужно откачивать буферы. Например, если вы помещаете «fullFence» до и после записи при добавлении «loadFence» до и после чтения в письменную переменную, вы все равно можете наблюдать устаревшие чтения. –

0

Я считаю, что эти методы не добавляют практически ничего на практике.

Правильно, они не добавили бы ничего в 99,9% приложений. Нужно только в очень конкретных случаях вам нужно было бы вызвать этот метод напрямую, а не использовать конструкцию более высокого уровня.

летучее чтение, отложенная запись и летучие записи соответственно,

Я прочитал это как «летучее чтение, летучая запись, летучая запись и чтения» Там, кажется, не быть ленивой/заказать запись забор.

loadFence() является забором приобретать и storeFence() является выпуск забора,

Я не считаю, что эти сдвиги к семантике приобретает/выпуск. Они более базовые, чем это. Например, в этих методах не происходит изменения состояния. для получения/выпуска требуется атомная операция, такая как compareAndSet, которая является другим небезопасным методом.

+0

Я имею в виду что-то вроде «AtomicInteger.lazySet()», когда я говорю «ленивый» напишу – ntysdd

+0

Я не понимаю, почему вы говорите, что не переводите на семантику получения/выпуска. Документ для loadFence() говорит: «Обеспечивает отсутствие переупорядочения нагрузок до забора с грузами или магазинами после забора». Это звучит почти так, как определение приобретающего барьера. – ntysdd

+0

@ntysdd Что вы подразумеваете под «приобретать барьер»? Они не читают и не пишут, что он приобретает или выпускает? Я предполагаю, что вы не говорите о Семафоре. –

Смежные вопросы