2013-11-13 3 views
0

Учитывая этот пример класс:Изменения переменного экземпляра из несинхронизированного/синхронного контекста

class Example { 
    String str = ""; 
    public synchronized boolean foo() { str = "foo"; } 
    public boolean bar() { str = "bar"; } 
    public synchronized boolean baz() { str = "baz"; } 
} 

С этого post, то ясно, что любой поток может вызвать метод bar. Скажем, нить T1 посередине выполнения foo() и нить. T2 звонки bar(). Может bar() переназначить str, хотя foo приобрел замок? Как насчет того же вопроса, если baz вызывается T2, хотя T2 находится в середине выполнения foo?

ответ

3

Вам необходимо сделать str volatile первым для потоков, чтобы быть в состоянии видеть друг друга, изменения еще останутся, они будут видеть только локальную копию.

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

Итак, чтобы ответить на ваш вопрос: Can bar() reassign str even though foo has obtained a lock? -> Да.

То же самое касается T2. Но вы не сможете гарантировать согласованное состояние, если вы не синхронизируете bar.

0

Говорите нить T1 находится в середине выполнения foo() и потоков T2 вызывает bar(). Может ли bar() переназначить str, хотя foo получил блокировку?

Да. Потому что, хотя foo() синхронизирован, bar() нет. Поток T1 получил блокировку объекта класса Example, и синхронизированные функции будут заблокированы, а не несинхронизированный.

Как насчет того же вопроса, если baz вызывается T2, хотя T1 равен в середине выполнения foo?

На этот раз, как и baz() функция синхронизации, T2 будет ждать, если T1 уже получил доступ к одной из synchronized функции (то есть, foo()) объекта класса Example.

0

синхронизированный выполняет следующие действия: if (позволяет сказать) 5 потоков запрашивают доступ, 4 переносятся на удержание и 1 пропускается. Вам всегда нужно синхронизировать что-то, потому что кто-то должен быть монитором, чтобы проверить, сколько потоков в строке, и будет выпущено дальше, как только текущий поток будет выполнен.

Но если у вас нет этого синхронизированного блока, никто не ограничивает доступ. То есть, как самый критический вышибала в клубе, а задняя дверь широко открыта. Несмотря на то, что «клуб» имеет синхронизированный доступ, даже лучший монитор (вышибала) не может остановить людей от использования задней двери, если он не знает об этом.

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