JavaRush /Курсы /Java Multithreading /Другие детали синхронизации и многонитиевости

Другие детали синхронизации и многонитиевости

Java Multithreading
7 уровень , 10 лекция
Открыта

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

Есть такая здоровенная тема, называется 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-машины.

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

Комментарии (69)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
arsvasimov Уровень 51
27 июня 2025
Ну норм так то
SomeBody098 Уровень 51
5 августа 2024
ок!
Ivan Pavlichenko Уровень 30
26 февраля 2024
Что это было?
Виктор Уровень 40
24 августа 2023
Джавараш, может поменяете в правилах "happens-before" на человеческие "случается раньше" или "случается прежде" и измените окончания у слов после этого словосочетания. Чтоб это читалось по человечески и мозг мог вникнуть в суть, а не пытаться сконструировать предложения так чтобы это было на русском, а не на албанском.
Anemon Уровень 13 Expert
5 января 2025
Это особое правило языка, оно вот так вот пишется. Можно было, конечно, написать по человечески, но и причина почему написано именно так в целом понятна..
Rolik Уровень 41
24 апреля 2023
Правила happens - before на человеческом: happens-before - правила синхронизации локальной и глобальной памяти записи/чтения потоков: • освобождение mutex одним потоком раньше захвата другим; • метод start() выполняется раньше метода run(); • метод run() выполняется раньше метода join(); • запись в поле volatile long/double происходит раньше считывания из него.
Griboed Уровень 30
9 апреля 2023
Вот интересно. Дан список условий синхронизации памяти. И первым же пунктом (первым условием) идет: "В рамках одной нити любая команда happens-before (читается «случается перед») любой операцией, следующей за ней в исходном коде." А условие синхронизации, собственно, в чем заключается? Ну да, одна команда, написанная выше другой команды выполнится раньше последней. Но а память из-за какого условия должна синхронизироваться?
Rolik Уровень 41
24 апреля 2023
Условие - синхронизация локальных и глобального потока. Т.е., куда будет писаться и откуда считываться кэш тбоего потока. Опять же это все для long и doble.
kalkulator¹ Уровень 51
3 февраля 2023
ниткі сложно 🌶🌶
И. Ж. Уровень 41
2 февраля 2023
Такое ощущение что пропущены слова глаголы в условиях, из за чего бессвязно и непонятно ничего вообще
Александр Уровень 40
31 октября 2022
не рефлексуй за свою пидагогику риша я уже давно только задачи читаю
Александр Уровень 40
31 октября 2022
вернулся добавить: и картинки смотрю! спойлер : на следущей странице котоктулх! сходи. позырь.вернись.плюсани!
BobaFoba Уровень 28
28 августа 2022
Лучше напишите так: "Перед вызовом метода interrupt(), когда он был вызван либо путем выбрасывания исключения InterruptedException, либо с помощью методов isInterrupted() или interrupted()" А то дичь какая-то, читать невозможно