Что такое Java Memory Model?android-220

Основное определение

Java Memory Model — это формальная спецификация, которая определяет:

  • Как потоки взаимодействуют через общую память
  • Каким образом изменения переменных становятся видимыми между потоками
  • Какие гарантии порядка выполнения операций предоставляет JVM

Ключевые проблемы, которые решает JMM

  1. Видимость изменений (Visibility):

    • Когда запись в одном потоке станет видна другому потоку
  2. Порядок выполнения (Ordering):

    • В каком порядке потоки видят операции других потоков
  3. Атомарность операций:

    • Какие операции гарантированно выполняются как единое целое

Основные концепции JMM

1. Happens-Before

Отношение порядка между операциями, гарантирующее видимость изменений:

Если операция A happens-before операции B, то результат A виден для B

Примеры happens-before:

  • Запуск потока happens-before его первая операция
  • Освобождение монитора (unlock) happens-before последующее захват (lock) того же монитора

2. Работа с памятью

  • Main Memory — центральное хранилище данных
  • Working Memory — локальная копия данных потока
Поток 1: Working Memory ←→ Main Memory
Поток 2: Working Memory ←→ Main Memory

3. Volatile переменные

Гарантируют:

  • Видимость изменений сразу для всех потоков
  • Запрет переупорядочивания операций с volatile-доступами
volatile boolean flag = false;

// Поток 1:
flag = true; // Запись сразу видна другим потокам

// Поток 2:
while(!flag); // Увидит изменение немедленно

Практические аспекты JMM в Android

1. Безопасная публикация объектов

Правильные способы опубликовать объект для других потоков:

// 1. Через volatile
volatile MyObject obj;

// 2. Через final поля
class Holder {
    final MyObject obj;
    Holder(MyObject o) { this.obj = o; }
}

// 3. Через synchronized
synchronized void setObject(MyObject o) {
    this.obj = o;
}

2. Аннотации для JMM

В Android часто используют:

@GuardedBy("lock")
private Object sharedData;

@Volatile
private boolean isReady;

Примеры проблем без JMM

  1. Неправильная видимость:
// Без синхронизации может работать некорректно
boolean running = true;

void stop() { running = false; } // Может никогда не стать видимым
  1. Переупорядочивание операций:
// JVM может поменять порядок инициализации
objRef = new Object(); // Часть 1: выделение памяти
                      // Часть 2: инициализация (может быть переупорядочена)

Гарантии JMM

  1. Для synchronized:

    • Атомарность входа/выхода
    • Видимость изменений до/после блока
  2. Для final полей:

    • Правильная инициализация видна всем потокам
  3. Для volatile:

    • Атомарность чтения/записи
    • Запрет переупорядочивания

Резюмируем:

Java Memory Model — это фундаментальная спецификация, определяющая правила работы с памятью в многопоточной среде. Понимание JMM критически важно для написания корректных concurrent-приложений в Android, особенно при работе с SharedPreferences, LiveData и другими компонентами, где важна видимость изменений между потоками.