2013-02-09 3 views
8

из книги Java параллелизма на практике:финал против летучего guaranntee w.rt к безопасной публикации объектов

Чтобы опубликовать объект безопасно, как ссылки на объект и состояние в объекта должны быть сделаны видимо другие темы одновременно. правильно построенный объект может быть безопасно опубликовано:

  • Инициализация ссылки на объект от статического инициализатора

  • хранящего ссылку на него в летучее поле или AtomicReference

  • хранящема ссылка на него в окончательное поле правильно построенного объекта

  • St ссылаясь на него в поле, которое должным образом защищено замком
    .

Мои вопросы:

  1. Каковы различия между пулевыми пунктами 2 и 3? Меня интересует разница между volatile подхода и final подход с точки зрения безопасной публикации объекта.
  2. Что он подразумевает под конечным полем правильно построенного объекта в пункте 3? Прежде чем начинать маркированные точки, авторы уже упомянули, что они говорят о правильно построенном объекте (который, я полагаю, не позволяет ссылаться на ссылку this). Но еще раз, почему они упоминали о правильно построенных объектах?

ответ

7

В чем разница между точками пули 2 и 3?

  • volatile в основном означает, что какая-либо запись в этой области будут видны из других потоков. Поэтому, когда вы объявляете поле изменчивым: private volatile SomeType field;, вам гарантируется, что если конструктор пишет в это поле: field = new SomeType();, это назначение будет видно из других тем, которые впоследствии попытаются прочитать field.
  • final имеет весьма схожую семантику: у вас есть гарантия, что если у вас есть конечное поле: private final SomeType field; запись в это поле (либо в объявлении, либо в конструкторе): field = new SomeType(); не будет изменен и будет виден другим нити , если объект правильно опубликован (т.е. нет выхода this).

Очевидно, что основное отличие заключается в том, что если поле является окончательным, его можно назначить только один раз.

Что он подразумевает под конечным полем правильно построенного объекта в точке 3?

Если, например, вы позволяете this побег из конструктора, гарантия от финальной семантики ушла: если наблюдающая поток может видеть поле со значением по умолчанию (нуль для объекта). Если объект правильно построен, этого не может произойти.


надуманный пример:

class SomeClass{ 
    private final SomeType field; 

    SomeClass() { 
     new Thread(new Runnable() { 
      public void run() { 
       SomeType copy = field; //copy could be null 
       copy.doSomething(); //could throw NullPointerException 
      } 
     }).start(); 
     field = new SomeType(); 
    } 
} 
+0

Если после построения я изменяю состояние объекта, на которое ссылается поле, например 'field.setX (new X())', является ли это изменение также гарантированным для просмотра другими потоками, когда мы объявляем его изменчивым? Или это только обеспечивает безопасность инициализации? А как насчет финала в этом случае? – Geek

+0

Нет, только «поле» дает вам гарантию видимости при (пере) назначении. Если 'x' также нестабилен,' field.x = new X(); '(или ваш пример сеттера) не дает такой гарантии. – assylias

+0

То же самое касается финала, и следствие состоит в том, что если все члены «поля» являются окончательными и неизменяемы, «поле» является неизменным и, следовательно, является потокобезопасным. – assylias

1

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

Я считаю, что правильно построенный объект действительно то, что вы имеете в виду, объект которого this ссылка не миновал его конструктор и был опубликован в безопасной манере к потоку, который используется в.

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

  • Нет связанных вопросов^_^