Требуется ли модификатор volatile
при работе с блокировками, чтобы гарантировать видимость памяти?
Пытаясь полностью понять параллелизм, видимость памяти и контроль выполнения, я натолкнулся на несколько источников, сообщающих, что переменные обновляются в блоках synchronized
.не требовать, чтобы поле было volatile
(в основном источники не указаны, и фактически одна страница, в которой говорится, что синхронизированные методы и поля волатильности должны использоваться совместно).
При приближении к главе jls 17.4.5 Я обнаружил:
Два действия могут быть упорядочены с помощью отношения «до того».Если одно действие происходит перед другим, то первое видно и упорядочено перед вторым.
В этом разделе говорится, что последующие синхронизированные вызовы метода, защищающие одну и ту же переменную переменной, обеспечат еевиден второй поток?Если это так, то же самое относится и к блокировкам, поскольку мы также можем гарантировать порядок?
С другой стороны, что происходит, когда внезапно возникают блокировки записи, позволяющие двум потокам получить доступ к полю.Разве вся конструкция разрушается, и потоки никогда не гарантируют обновление своего кэша даже в том случае, если переменная разблокирована?
В кратком коде
int field; //volatile not needed because we have a definite happens-before relationship
Lock lock;
void update(){
//No matter how many threads access this method they will always have
//the most up to date field value to work with.
lock.lock()
field *= 2;
lock.unlock();
}