исключает ли использование synchronized, volatile?
Происходит ли сброс данных из кэшей по завершению synchronized блока, и используют ли другие потоки потом обновлённые данные непосредственно из оперативки (игнорируя свои кэши)
Да, обращение к неволатильным переменным из синхронизированного блока гарантирует видимость, упорядоченность и атамарность. Но стоит иметь ввиду, что вход в синхронизированный блок на много медленнее обращения к волатильной переменной.
volatile действительно позиционируется как легковесная альтернатива synchronized когда речь идет о доступе к одной переменной.
На более ранних реализациях JVM мне доводилось также наблюдать феномен, когда несинхронизированный код работал как синхронизированный, когда в нем был включен трейсинг в консоль; когда же трейсинг выключался, код переставал работать. имхо, это было связано с тем, что PrintStream.println синхронизирован.
Однако я не видел такой спеки, которая бы определяла, что потоки должны синхронизировать кэши с общей памятью. Более того, спецификация Memory Model говорит следующее:
An implementation is free to produce any code it likes, as long as all resulting executions of a program produce a result that can be predicted by the memory model.
т.е. если некая реализация JVM будет работать эффективнее не сбрасывая весь кэш, а лишь те переменные, которые требуются согласно спецификации, то код, опирающийся на недокументированное поведение - сброс кэша потока, вероятно перестанет работать корректно.
Т.о. даже если сброс кэша и происходит в некоторых реализациях JVM, он не гарантирован спецификацией и не стоит опираться на это поведение в своей программе.
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости