2013-09-26 5 views
5

После прочтения кучу вопросов/статей по этой теме для меня все еще остается одна вещь.Относительно летучих и синхронизированных

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

Моя проблема заключается в том, что ничто из того, что я читал, никогда не заявляет, что синхронизация на переменной приведет к такому же поведению, но часто предоставляет пример кода, в котором указано, что в следующих двух случаях значение, которое считывается из переменная будет в курсе:

volatile int x; 
... 
int y = x; 

и

final Object lock = new Object(); 
int x; 
... 
synchronized(lock) { 
    int y = x; 
} 

вопрос заключается в том, то: это тот случай, когда синхронизация по любой произвольной переменной заставит каждого ва доступный в синхронизированном блоке для доступа к самому последнему значению этой переменной?

+0

Не могу ответить на ваш вопрос, но я должен сказать, что ваше название ... является эпическим. Заставляет меня думать о том, как Толкин открыл «Властелин колец», «Что касается хоббитов». – StormeHawke

ответ

5

это тот случай, когда синхронизация по любому произвольных переменным заставят каждый переменный доступ в пределах синхронизированного блока, чтобы получить доступ к наиболее актуальной стоимости этого переменной ?

Вы можете синхронизировать любую переменную для чтения, если запись этой переменной выполнялась при синхронизации одной и той же переменной.

В вашем примере, так долго, как нечто подобное происходит следующее затем все записи, которые имели место до записи в x будут видны после последующего чтения:

synchronized(lock){ 
    x = 10; 
} 

Так к вашему раннему пункту:

... ничего, что я читал когда-либо явно указывает, что синхронизация на другой переменной будет вызывать такое же поведение ...

Это потому, что оно не дает такого же поведения.Происходит, прежде, чем отношения occurrs на несколько раз, два важных в вашем случае являются

  1. записи и последующее чтение одного и тем же изменчивого переменной
  2. выхода и последующий ввод монитора на одном объекте
2

Существует поучительная статья here где упоминаются:

В модели Java-память летучего поле имеет магазин барьер вставлен после записи к нему и барьер в нагрузки вставленной перед читать его. ...

Обратите внимание, что нет ничего конкретного к тому, что поле осуществляется доступ. Это означает, что доступ к любым летучим полем создает барьер для всех кэшированных переменных.

Синхронизация имеет аналогичную функциональность.

+1

Это неточно. Именно так построены большинство реализаций JMM, но сам JMM не гарантирует, что => я бы не стал на него полагаться. – assylias

Смежные вопросы