Сегодня я весь день исследовал модель памяти Java, чтобы подробно понять проблемы с JMM до Java 5 и изменения, внесенные JSR-133, реализованные в Java 5.
На что я не могу найти окончательный ответ, так это на объем аннулирования и очистки кеша, необходимых для конкретной синхронизации.
Должны ли все регистры и кеши ЦП быть недействительными при входе в любую синхронизированную часть кода и все сбрасываться в основную оперативную память при выходе, или JVM разрешено аннулировать только те переменные, которые фактически читаются, и сбрасывать только те, которые фактически записаны во время синхронизированного блока кода?
Если первое, то почему JMM так педантично настаивает на том, что барьер памяти возникает только между двумя потоками, которые синхронизируются с одним и тем же объектом?
Если последнее, есть ли хороший документ, объясняющий детали того, как это достигается? (Я полагаю, что базовая реализация должна будет установить флаг «обхода кешей» на уровне ЦП в начале синхронизированного блока и очистить его в конце, но я мог найти ошибку. )