JavaRush /Курсы /Модуль 2. Java Core /Условия синхронизации памяти

Условия синхронизации памяти

Модуль 2. Java Core
12 уровень , 9 лекция
Открыта

— Привет, Амиго!

Есть такая здоровенная тема, называется Java Memory Model. В принципе знать ее тебе пока не обязательно, но услышать про это – будет полезно.

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

— И сложнее!

— Да, лучше и сложнее. Это как самолет. Летать на самолете лучше, чем идти пешком, но сложнее. Попробую объяснить тебе новую ситуацию очень упрощенно.

Вот что было придумано. В код был добавлен механизм синхронизации локальной памяти нитей, названный «happens before» (дословно «случилось перед»). Был придуман ряд правил/условий, при наступлении которых память синхронизируется – обновляется до актуального состояния.

Пример:

Порядок Нить 1 Нить 2
1
2

101
102
103
104
105

201
202
203
204
205
public int y = 1;
public int x = 1;

x=2;
synchronized(mutex)
{
 y = 2;
}
нить ждет освобождения мютекса — mutex

synchronized(mutex)
{
 if (y == x)
 System.out.println("YES");
}

Одно из таких условий – это захват освобожденного мютекса. Если мютекс был освобожден и снова захвачен, то перед захватом обязательно выполнится синхронизация памяти. Нить 2 увидит «самые новые» значения переменных x и y, даже если не объявлять их volatile.

— Как интересно. И много таких условий?

— Достаточно, вот некоторые условия синхронизации памяти:

  • В рамках одной нити любая команда happens-before (читается «случается перед») любой операцией, следующей за ней в исходном коде.
  • Освобождение лока (unlock) happens-before захватом того же лока (lock).
  • Выход из synchronized блока/метода happens-before вход в synchronized блок/метод на том же мониторе.
  • Запись volatile поля happens-before чтение того же самого volatile поля.
  • Завершение метода run экземпляра класса Thread happens-before выход из метода join() или возвращение false методом isAlive() экземпляром той же нити.
  • Вызов метода start() экземпляра класса Thread happens-before начало метода run() экземпляра той же нити.
  • Завершение конструктора happens-before начало метода finalize() этого класса
  • Вызов метода interrupt() на нити happens-before, когда нить обнаружила, что данный метод был вызван, либо путем выбрасывания исключения InterruptedException, либо с помощью методов isInterrupted() или interrupted()

— Т.е. все немного сложнее, чем я думал?

— Да, немного сложнее…

— Спасибо, Риша, буду думать.

— Не заморачивайся сильно на эту тему. Придет время, сам все поймешь. Пока тебе лучше разбираться в основах, чем лезть в дебри внутреннего устройства Java-машины.

— О_о. М-да. Некоторые вещи лучше не знать.

Комментарии (10)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Anonymous #3613348 Уровень 40
9 января 2026
— Достаточно, вот некоторые условия синхронизации памяти: В рамках одной нити любая команда случается перед любой операцией, следующей за ней в исходном коде. Освобождение лока (unlock) случается перед захватом того же лока (lock). Выход из synchronized блока/метода случается перед входом в synchronized блок/метод на том же мониторе. Запись volatile поля случается перед чтением того же самого volatile поля. Завершение метода run экземпляра класса Thread случается перед выходом из метода join() или возвращением false методом isAlive() экземпляром той же нити. Вызов метода start() экземпляра класса Thread случается перед началом метода run() экземпляра той же нити. Завершение конструктора случается перед началом метода finalize() этого класса Вызов метода interrupt() на нити случается перед тем, когда нить обнаружила, что данный метод был вызван, либо путем выбрасывания исключения InterruptedException, либо с помощью методов isInterrupted() или interrupted(). На мой взгляд, лексически верным было бы использовать слово "происходит" вместо "случается". Но это уже моё желание сделать текст максимально понятным.
Мая Уровень 82
20 июля 2025
"Завершение конструктора happens-before начало метода finalize() этого класса" - это точно на русском написано?
Юрій Уровень 87
5 июля 2025
— Да, немного сложнее…
Олег Уровень 109 Expert
12 марта 2024
....В рамках одной нити любая команда happens-before (читается «случается перед») любой операцией, следующей за ней в исходном коде. Как это понять?((
Иван Корниенко Уровень 109
27 марта 2024
Нужно прямо взять этот термин и заменить на перевод. Получится: "В рамках одной нити любая команда случается перед любой операцией, следующей за ней в исходном коде".
Владимир Кругман Уровень 51 Expert
7 декабря 2023
Эта лекция могла бы содержать всего одну строку

— Не заморачивайся сильно на эту тему. 
Зачем включили в список тем, если и тему не раскрыли и в конце одной фразой обесценили и значимость темы, и затраченное время на лекцию?
Uladzislau Уровень 109 Expert
12 ноября 2023
https://g.co/bard/share/05c5968ca7df Bard перефразировал немного попроще :)
Артемий Уровень 59
23 июля 2022
Некоторые вещи лучше не знать
Владимир Уровень 109 Expert
21 июня 2022
Эх, а ведь еще недавно напишешь такой System.out.println("Яж программис"); и пошел мордой крутить довольной.
Елена Уровень 108 Expert
11 мая 2022
Вот это изложено так, что совершенно не понятно от чём говорится. Какой-то сумбур. 🤪 Вот это выражение "happens-before" сбивает с толку, не ложится в контест фразы, как не переводи его в тексте. "happens-before" - вообще не понятно, то ли это специальный термин, то ли ключевое слово, то ли переводчик не стал заморачиваться. В итоге получили уродливую формулировку, которую невозможно инерпретировать и понять хоть какой-то смысл написанного. Сделайте вменяемый перевод, который передаёт смысл, а выражение "happens-before" дайте в примечании. "— Достаточно, вот некоторые условия синхронизации памяти: В рамках одной нити любая команда happens-before (читается «случается перед») любой операцией, следующей за ней в исходном коде. Освобождение лока (unlock) happens-before захватом того же лока (lock). Выход из synchronized блока/метода happens-before вход в synchronized блок/метод на том же мониторе. Запись volatile поля happens-before чтение того же самого volatile поля. Завершение метода run экземпляра класса Thread happens-before выход из метода join() или возвращение false методом isAlive() экземпляром той же нити. Вызов метода start() экземпляра класса Thread happens-before начало метода run() экземпляра той же нити. Завершение конструктора happens-before начало метода finalize() этого класса Вызов метода interrupt() на нити happens-before, когда нить обнаружила, что данный метод был вызван, либо путем выбрасывания исключения InterruptedException, либо с помощью методов isInterrupted() или interrupted()"