2012-04-19 1 views
0
public Foo getFoo(){ 
    Foo foo = null; 

    synchronized(fooList){ 
     if(fooList.size() > 0){ 
      foo = fooList.remove(0); 
     } 
    } 

    return foo; 
} 

С foo объявлен за пределами синхронизированного блока, существует ли потенциал для возврата плохих данных?Является ли метод потокобезопасным, если возвращаемое значение объявлено/возвращено вне синхронизированного блока?

+0

все в порядке, но пример, который вы дали, не мотивирует существование 'foo'. Просто говоря: 'return fooList.remove (0)' неприемлемо в вашем контексте? –

+0

@MarkoTopolnik, это устаревший код. : D – user1329572

ответ

3

Каждый экземпляр потока, вызывающий getFoo(), будет иметь свой собственный экземпляр foo. Таким образом, foo является потокобезопасным и не нуждается в синхронизации.

1

Что означает «плохие данные» в этом контексте? fooList может измениться асинхронно до synchronized(fooList) и после соответствующей закрывающей фигурной скобки, перед return foo; (в общем, до момента использования возвращаемого значения.) Какова ваша конечная цель?

+0

Если этот метод возвращает 'null', то логика заключается в том, что' fooList' пуст. Я хочу убедиться, что этот метод не возвращает 'null', когда' fooList' не пуст. – user1329572

+1

ОК, я понял. Если в момент блокировки монитора для 'fooList' он не пуст (и все обращения к' fooList' синхронизированы на нем!), То вы никогда не получите 'null'. –

1

getFoo не будет возвращать устаревшие данные, поскольку Foo foo является локальным переменным и fooList синхронизируется

Локальных переменным является поточно, так как каждый вызов потока будет создавать новый объект Foo, вместо обмена одного объекта. Хотя переменная не является потокобезопасной, поскольку несколько потоков могут обращаться к fooList, но в этом случае fooList уже синхронизирован.

+0

Итак, локальные переменные по сути являются потокобезопасными? – user1329572

+1

@ user1329572 см. Мой обновленный ответ –

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