Я до сих пор довольно новичок в концепции потоковой обработки и стараюсь больше узнать об этом. Недавно я наткнулся на сообщение в блоге "Что летучие средства в Java" Джереми Мэнсона, где он пишет:
Когда один поток записывает в изменчивую переменную, а другой поток видит которые пишут, первый поток сообщает второй о всемсодержимое памяти до тех пор, пока она не выполнит запись в эту изменчивую переменная. [...] все содержимого памяти, просмотренного Thread 1, до он написал
[volatile] ready
, должен быть видимым для Thread 2, после него читает значениеtrue
дляready
. [выделено мной мной]
Теперь, означает ли это, что все переменные (volatile или нет), хранящиеся в памяти Thread 1 во время записи в переменную volatile, станут видимыми для Thread 2 после того, как она прочитает эту изменчивую переменную? Если это так, можно ли скомпрометировать этот оператор вместе с официальными документами Java/Oracle? И из какой версии Java он будет работать?
В частности, если все потоки разделяют следующие переменные класса:
private String s = "running";
private volatile boolean b = false;
И Thread 1 выполняет следующее:
s = "done";
b = true;
Затем Thread 2 затем выполняет (после того, как Thread 1 написал в поле volatile):
boolean flag = b; //read from volatile
System.out.println(s);
Можно ли гарантировать печать "сделано"?
Что произойдет, если вместо объявления b
как volatile
я помещу запись и чтение в блок synchronized
?
Кроме того, в обсуждении, озаглавленном "Связаны ли статические переменные между потоками?, @TREE пишет
Не используйте volatile для защиты более чем одной части общего состояния.
Почему? (Извините, я еще не могу комментировать другие вопросы, или я бы спросил там...)