Насколько я понимаю, поскольку запись в значение выполняется в синхронизированном блоке, поэтому последнее значение в любом случае будет видно другим потокам
Это неверно. Как правило, нет никакой гарантии, что другие потоки «увидят» изменения в переменных, как только они будут внесены. Поток может видеть устаревшее значение для измененной переменной, потому что, например, поток видит значение в регистре, а не в основной памяти.
Переменная volatile
устанавливает семантику "происходит до". JLS, раздел 17.4.5 , состояния:
С помощью отношения случай-до можно заказать два действия. Если одно действие происходит до другого, то первое видно и упорядочено до второго.
- Запись в поле
volatile
(§8.3.1.4) происходит до при каждом последующем чтении этого поля.
JLS, раздел 8.3.1.4 :
Поле может быть объявлено volatile
, и в этом случае Модель памяти Java гарантирует, что все потоки увидят согласованное значение для переменной (§17.4).
Причина, по которой поле должно быть volatile
, заключается в том, что, хотя чтение является атомарным, оно должно гарантировать, что значение является текущим - что любое значение, ранее записанное другим потоком, является видимым. Чтение, являющееся атомарным, недостаточно; volatile
все еще необходимо для обеспечения согласованности значения.