Видимость параллелизма Java

У меня есть вопрос о видимости в java. Видимость может появиться только в том случае, если у нас есть как минимум два потока, которые работают как минимум на 2 ядрах процессора. Это правильно? Каждое ядро ​​может кэшировать переменные в своих регистрах и кэш-памяти, из-за чего могут возникнуть проблемы с видимостью. Но что, если у нас есть n потоков и все они работают на одном ядре процессора (конечно, мы не можем быть уверены, что они будут работать только на одном ядре, но предположим, что это возможно), то нет никакого способа иметь видимость памяти? Или это не правильно? Заранее спасибо.


person DPM    schedule 29.07.2015    source источник
comment
Что вы подразумеваете под видимостью памяти?   -  person ControlAltDel    schedule 29.07.2015
comment
Один поток для изменения переменной, а другой поток не видит этого изменения. Извините, если я не использовал правильный термин.   -  person DPM    schedule 29.07.2015
comment
Я не знаю ответа, но я должен спросить: какая разница? Если бы вы узнали, что многопоточные программы, работающие на одноядерной машине, не будут подвержены ошибкам параллелизма, как если бы они работали на нескольких ядрах, стали бы вы писать код с ошибками? Я недостаточно разбираюсь в процессорах и реализации JVM, чтобы сказать, но даже в одном ядре кажется, что данные, извлеченные из основной памяти в кеш, могут быть признаны недействительными до того, как они будут прочитаны, что создает проблему видимости на одном ядре.   -  person erickson    schedule 29.07.2015
comment
Я хочу это знать, потому что это поможет мне понять, как это работает. Мой код не будет зависеть от этого.   -  person DPM    schedule 30.07.2015


Ответы (2)


Если под видимостью понимать разделяемую память, чтобы объекты, которые создаются или изменяются в одном потоке, могли быть видны и в другом потоке, то сколько бы ядер ни было, видимость останется прежней. Java дает обещания в соответствии с Спецификацией языка Java, в частности Модель памяти Java, которой необходимо следовать независимо от количества ядер.

Но что, если у нас есть n потоков и все они работают на одном ядре процессора (конечно, мы не можем быть уверены, что они будут работать только на одном ядре, но предположим, что это возможно), то нет никакого способа иметь видимость памяти? Или это не правильно?

Да, видимость (общая память) по-прежнему существует, если на одном ядре работает n потоков. Но есть некоторые предостережения, которые существуют независимо от того, сколько ядер. Главным образом то, что каждый поток имеет свою собственную кэшированную память, и переменная может иметь разные значения в обоих потоках. Если переменная volatile, то значение этой переменной всегда будет обновляться во всех потоках.

Поле может быть объявлено volatile, и в этом случае модель памяти Java гарантирует, что все потоки видят согласованное значение переменной (§17.4).

Я рекомендую вам больше узнать о модели памяти Java.

person Jose Martinez    schedule 29.07.2015
comment
Вообще-то я не подумал о том, что у каждого потока свой кеш, а не только у разных ядер. Спасибо ! - person DPM; 30.07.2015

Даже на 1 ядре с несколькими потоками у вас все еще может быть то, что вы называете этой проблемой «видимости», поскольку потоки, которые загрузили значение из памяти в регистр, сохранят это значение в стеке этого потока и не увидят обновление, если поток выключается, а затем снова включается, если переменная/память объявлена ​​volatile

person ControlAltDel    schedule 29.07.2015
comment
Видимость — это общий термин, используемый в Спецификации языка Java и в других местах. - person erickson; 29.07.2015
comment
А можете привести пример обновления стека, которое видно другому потоку? Есть только локальные переменные, которые ограничены стеком, и поля, которые находятся в куче, поэтому я не понимаю, какие обновления вы имеете в виду. - person erickson; 29.07.2015
comment
Низкоуровневая реализация многопоточности может оставить некоторые переменные не строго в стеке или куче. Они могут храниться в регистрах, которые видны только потоку. Дело в том, что вы действительно не знаете, и должны предположить, что параллелизм требует соответствующей синхронизации, а не делать предположения о вашей среде выполнения. - person Daniel; 29.07.2015
comment
Что-то вроде собственного стекового фрейма? Это имеет смысл. - person erickson; 29.07.2015