Является неустойчивым к использованию на процессорах x86

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

Означает ли это, что мы можем кодировать, не используя "volatile" keywoard в java, если мы планируем работать только на процессорах x86?

Обновление:

Хорошо, полагая, что мы не учитываем вопрос о переупорядочении команд, можем ли мы предположить, что проблема присвоения энергонезависимого поля, не являющегося видимым по всем ядрам, отсутствует на процессорах x86?

Ответ 1

Нет - ключевое слово volatile имеет больше последствий, чем когерентность кэша; он также устанавливает ограничения на то, что может и не может выполнять среда выполнения, например, задерживать вызовы конструктора.

Ответ 2

О вашем обновлении: Нет, мы не можем. Другие потоки могут просто читать устаревшие значения без обновления переменной. И еще одна проблема: JVM разрешено оптимизировать код, если он может гарантировать правильность однопоточного поведения.

Это означает, что что-то вроде:

public boolean var = true;
private void test() {
    while (var) {
       // do something without changing var
    }
}

может быть оптимизирован JIT до while (true), если он хочет!

Ответ 3

Существует большая разница между can sync the value of fields и always syncs the value of fields. x86 может синхронизировать поля, если у вас есть volatile, иначе это не так и не должно.

Примечание: волатильный доступ может быть на 10-30 раз медленнее, чем энергонезависимый доступ, что является основной причиной, по которой оно не выполняется все время.

Кстати: Вы знаете какие-либо многоядерные простые процессоры x86. Я бы подумал, что большинство из них были x64 с поддержкой x86.

Ответ 4

Есть очень точные спецификации того, как JVM должен вести себя для volatile, и если он решит это сделать, используя инструкции, специфичные для процессора, тогда вам хорошо.

Единственное место, где вы должны сказать: "Мы знаем, что на этой платформе процессор ведет себя как.." - это когда вы связываетесь с родным кодом, где он должен соответствовать процессору. Во всех остальных случаях напишите спецификацию.

Обратите внимание, что ключевое слово volatile очень важно для написания надежного кода, работающего на нескольких процессорах, каждый со своим собственным кешем, поскольку он сообщает JVM игнорировать локальный кеш и получать официальное значение вместо кэшированного значения с 5 минут назад. Вы вообще этого хотите.

Ответ 5

запись в байт-код даже не должна приводить к записи в машинный код. если это не изменяет запись.

Ответ 6

Я могу поручиться за volatile. Я был в ситуации, когда один поток имеет "null" для переменной, а другой имеет правильное значение для переменной, которая была установлена ​​в этом потоке. Это не забавно отлаживать. Используйте volatile для всех общих полей:)