Можно ли использовать гарантии видимости вместо полноценной блокировки для доступа к общему состоянию потокобезопасным способом? - PullRequest
1 голос
/ 03 июня 2019

Java Concurrency на практике гласит следующее:

Когда поток A выполняет синхронизированный блок, а затем поток B входит в синхронизированный блок, защищенный той же блокировкой, значения переменных, которые были видимы дляA до снятия блокировки гарантированно будут видны B при получении блокировки.Другими словами, все, что A * в или до синхронизировало блок, видимо B, когда он выполняет синхронизированный блок, защищенный той же блокировкой.Без синхронизации такой гарантии нет.

Here's a diagram from the book

Та же логика применима к переменным переменным:

Эффекты видимости изменчивых переменныхвыходить за пределы значения самой изменчивой переменной.Когда поток A выполняет запись в переменную volatile, а затем поток B читает эту же переменную, значения всех переменных, которые были видны A до записи в переменную volatile, становятся видимыми для B после чтения переменной volatile.

Из описания очень ясно, что вы можете использовать этот эффект видимости для фактической замены (или ограничения использования) традиционных блокировок, когда вам нужно получить доступ к некоторому общему состоянию.В примере из диаграммы вы можете видеть, что поток B может безопасно прочитать переменную y, даже если она была изменена в потоке A вне синхронизированного блока.

Итак, безопасно ли использовать это visibility guaranteeкогда вы изменяете какое-то общее состояние перед тем, как заблокировать поток, затем берете блокировку, делаете что-то (или ничего, я полагаю), снимаете блокировку, а затем в другом потоке вы получаете такую ​​же блокировку, снимаете ее и затем безопасно читаетепоследние значения из общих переменных, которые были обновлены в первом потоке?

Ответы [ 2 ]

2 голосов
/ 03 июня 2019

В цитируемом предложении есть ключевая часть:

Эффекты видимости изменчивых переменных выходят за пределы значения самой изменчивой переменной. Когда поток A записывает в энергозависимую переменную, а затем поток B считывает эту же переменную , значения всех переменных, которые были видны A до записи в энергозависимую переменную, становятся видимыми для B после чтения энергозависимой переменной.

Хотя это, очевидно, верно, вы получили здесь условие о записи A до чтения B. Порядок чтения / записи, однако, не может быть гарантирован без блокировки - и в этом весь смысл.

Таким образом, вы не можете заменить каждую синхронизацию на летучие, так как она не даст те же результаты.

0 голосов
/ 03 июня 2019

Да, вы получаете visibility guarantee описанным способом, используя volatile, synchronized или любую другую форму блокировки, но не более .В частности, вы не получаете взаимный доступ и атомарность.

См. Также разделы в JLS о модели памяти JVM и соотношении случается до для гораздо большей детализации и глубины.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...