Многопоточный доступ и переменный кэш потоков

Я мог бы найти ответ, если бы прочитал полную главу/книгу о многопоточности, но мне нужен более быстрый ответ. (Я знаю, что этот вопрос о переполнении стека похож, но недостаточно.)

Предположим, что существует этот класс:

public class TestClass {
   private int someValue;

   public int getSomeValue() { return someValue; }
   public void setSomeValue(int value) {  someValue = value; }
}

Есть два потока (A и B ), которые обращаются к экземпляру этого класса. Рассмотрим следующую последовательность:

  1. А :getSomeValue()
  2. B :setSomeValue()
  3. А :getSomeValue()

Если я прав, someValue должен быть volatile, иначе 3-й шаг может не вернуть значение даты от -до -(, потому что A может иметь кэшированное значение ). Это верно?

Второй сценарий:

  1. B :setSomeValue()
  2. А :getSomeValue()

В этом случае A всегда будет получать правильное значение, потому что это его первый доступ, поэтому он еще не может иметь кэшированное значение. Это правильно?

Если к классу обращаются только вторым способом,нет необходимости в volatile/синхронизации, или нет?

Обратите внимание, что этот пример был упрощен, и на самом деле меня интересуют конкретные переменные-члены и методы в сложном классе, а не целые классы (, т.е. какие переменные должны быть изменчивыми или иметь синхронизированный доступ ). Суть в том, :, если больше потоков обращается к определенным данным, нужен ли синхронизированный доступ во что бы то ни стало, или это зависит от способа (, например. порядок )они получают к нему доступ?


Прочитав комментарии, я пытаюсь представить источник моего замешательства на другом примере:

  1. Из потока пользовательского интерфейса:threadA.start()
  2. threadA вызывает getSomeValue()и информирует поток пользовательского интерфейса
  3. Поток пользовательского интерфейса получает сообщение (в своей очереди сообщений ), поэтому он вызывает:threadB.start()
  4. threadB вызывает setSomeValue()и информирует поток пользовательского интерфейса
  5. Поток пользовательского интерфейса получает сообщение и каким-то образом информирует threadA (, например. очередь сообщений)
  6. threadA вызываетgetSomeValue()

Это полностью синхронизированная структура, но почему это означает, что threadA получит наибольшее значение даты от -до -на шаге 6? (, если someValueне изменчиво или не помещается в монитор при доступе из любого места)

6
задан Community 23 May 2017 в 12:06
поделиться