Подтвердить что ты не робот

Неверная ошибка Java Unsafe.storeFence()?

Java 8 добавила три забора в sun.misc.Unsafe.

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

Итак, я искал в Интернете и нашел ссылку .

Согласно вышеприведенной странице, я считаю, что эти методы практически ничего не добавляют на практике. Поправьте меня, если я ошибаюсь, грубо говоря, 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();

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

ИЗМЕНИТЬ

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

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

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

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

ДРУГОЕ ИЗОБРАЖЕНИЕ

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

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

Спасибо @john-vint

4b9b3361

Ответ 1

В 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();

Ответ 2

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

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

volatile read, ленивая запись и volatile write соответственно,

Я читал его как "изменчивое чтение, неустойчивую запись, волатильную запись и чтение". Кажется, что нет ленивого/упорядоченного забора записи.

loadFence() - это забор, а storeFence() - это забор,

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