Я мог бы найти ответ, если бы прочитал полную главу / книгу о многопоточности, но мне бы хотелось получить более быстрый ответ. (Я знаю, что этот вопрос о переполнении стека похож на , но недостаточно.)
Предположим, есть этот класс:
public class TestClass {
private int someValue;
public int getSomeValue() { return someValue; }
public void setSomeValue(int value) { someValue = value; }
}
Есть два потока (A и B), которые обращаются к экземпляру этого класса. Рассмотрим следующую последовательность:
- О: getSomeValue ()
- B: setSomeValue ()
- О: getSomeValue ()
Если я прав, someValue должен быть изменчивым, иначе третий шаг может не вернуть актуальное значение (потому что A может иметь кешированное значение). Это правильно?
Второй сценарий:
- B: setSomeValue ()
- О: getSomeValue ()
В этом случае A всегда будет получать правильное значение, потому что это его первый доступ, поэтому он еще не может иметь кешированное значение. Это правильно?
Если доступ к классу осуществляется только вторым способом, нет необходимости в энергозависимости / синхронизации, или это так?
Обратите внимание, что этот пример был упрощен, и на самом деле меня интересуют конкретные переменные и методы-члены в сложном классе, а не целые классы (т.е. какие переменные должны быть изменчивыми или иметь синхронизированный доступ). Главный вопрос: если к определенным данным обращается больше потоков, обязательно ли нужен синхронизированный доступ или это зависит от способа (например, порядка) доступа к ним?
Прочитав комментарии, я пытаюсь представить источник моего замешательства на другом примере:
- Из потока пользовательского интерфейса:
threadA.start()
- threadA вызывает
getSomeValue()
и сообщает потоку пользовательского интерфейса - Поток пользовательского интерфейса получает сообщение (в своей очереди сообщений), поэтому он вызывает:
threadB.start()
- threadB вызывает
setSomeValue()
и сообщает потоку пользовательского интерфейса - Поток пользовательского интерфейса получает сообщение и информирует threadA (каким-то образом, например, очередь сообщений)
- threadA вызывает
getSomeValue()
Это полностью синхронизированная структура, но почему это означает, что threadA получит самое актуальное значение на шаге 6? (если someValue
не является изменчивым или не помещается в монитор при доступе из любого места)