Гарантируется ли видимость для последовательных потоков, выполняемых для энергонезависимой переменной - PullRequest
0 голосов
/ 02 мая 2019

Я прочитал ниже ссылки:

http://tutorials.jenkov.com/java-concurrency/volatile.html

https://www.geeksforgeeks.org/volatile-keyword-in-java/

https://docs.oracle.com/javase/tutorial/essential/concurrency/atomic.html

Но мне все еще не ясно, каково ожидаемое поведение в следующем случае:

  1. У меня есть пул потоков, в котором поток используется повторно.
  2. У меня есть энергонезависимая переменная, к которой обращаются различные потоки из этого пула потоков.
  3. Потоки запускаются последовательно. (Да, они могут выполняться в одном потоке. Но, только для этого случая. Поэтому не спрашивайте, почему бы не использовать один поток)

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

Как java флэш-память перемещает локальный кэш в память после каждого выполнения?

И перезагружает ли поток локальный кеш перед каждым выполнением?

Продолжайте жаловаться, что есть раздел кода, который не указан в кавычках. Итак, я должен сделать это. Пожалуйста, помогите исправить.

Ответы [ 2 ]

1 голос
/ 03 мая 2019

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

1 голос
/ 02 мая 2019

Модель Java Memory Model может ответить на ваш вопрос: в модели памяти Java энергозависимое поле имеет барьер хранилища, вставленный после записи в него, и барьер загрузки, вставленный перед чтением его.Квалифицированным конечным полям класса вставляется барьер хранилища после их инициализации, чтобы гарантировать, что эти поля будут видимы после завершения конструктора, когда доступна ссылка на объект.

см. https://dzone.com/articles/memory-barriersfences

Другими словами: когда поток пытается прочитать из volatile var, JMM заставляет все процессоры, владеющие этой областью памяти, выполнять обратную запись в память из кэша локального процессора.Затем CPU загружает свое значение в локальный кеш при необходимости.

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

Да и нет.Ключевое слово Volatile просто для того, чтобы сделать значение переменной видимым для других потоков.Но если вам нужен только один поток чтения-записи в данный момент = вам нужна синхронизация.Если вам нужно предоставить только видимость = достаточно ключевого слова volatile.

Если вы не используете ключевое слово volatile и разделяете значение в потоках, оно может быть устаревшим или даже поврежденным.Для типа LONG Java делает 2 записи по 32 бита, и они не являются атомарными.Допустим, другой поток может прочитать значение между этими двумя записями.

...