— Привет, Амиго!
Есть такая здоровенная тема, называется Java Memory Model. В принципе знать ее тебе пока не обязательно, но услышать про это – будет полезно.
С целью устранить все возможные проблемы, в Java изменили механизм работы памяти. Теперь не просто память делится на локальный кэш нити и глобальную, но и механизм стал еще лучше.
— И сложнее!
— Да, лучше и сложнее. Это как самолет. Летать на самолете лучше, чем идти пешком, но сложнее. Попробую объяснить тебе новую ситуацию очень упрощенно.
Вот что было придумано. В код был добавлен механизм синхронизации локальной памяти нитей, названный «happens before» (дословно «случилось перед»). Был придуман ряд правил/условий, при наступлении которых память синхронизируется – обновляется до актуального состояния.
Пример:
Порядок | Нить 1 | Нить 2 |
---|---|---|
1 2 … 101 102 103 104 105 … 201 202 203 204 205 |
|
нить ждет освобождения мютекса — mutex
|
Одно из таких условий – это захват освобожденного мютекса. Если мютекс был освобожден и снова захвачен, то перед захватом обязательно выполнится синхронизация памяти. Нить 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-машины.
— О_о. М-да. Некоторые вещи лучше не знать.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ