Каково точное значение контекста final-field-safe в JLS

Термин final-field-safe context часто используется в параграфе 17.5.3 JLS (последующая модификация конечных полей). Хотя, как можно понять из спецификации (если я здесь не прав, поправьте меня)

An implementation may provide a way to execute a block of code
in a final-fieldsafe context.

точное поведение зависит от реализации, до сих пор нет четкого определения термина.
Могу ли я предположить, что если у нас есть фиксация конечного поля F (то, что происходит в конце построения объекта или финальное поле, установленное с помощью API отражения) и действие < em> A, так что происходит-раньше (F, A), тогда A находится в контексте final-field-safe ?


person mkrakhin    schedule 09.09.2014    source источник


Ответы (1)


Чтобы понять, что такое JLS 17.5. 3 означает, что под «безопасным контекстом последнего поля» рассмотрим следующий код

public static final AccountType SINGLETON_ACCOUNT_TYPE = new AwesomeAccountType();

До Java 5 в Java была «особенность», в которой разработчики считали безопасность потоков при создании AwesomeAccountType и ее присвоение SINGLETON_ACCOUNT_TYPE безопасным. К сожалению, спецификация была неоднозначной и / или не указала поведение, что привело к тому, что разные реализации JVM имели разное поведение. В результате в этом сценарии Java часто не была потокобезопасной и переносимой.

Причина этого заключалась в том, что порядок операций, задействованных в создании AwesomeAccountType, мог быть переупорядочен во время выполнения таким образом, чтобы ссылка на объект могла стать видимой для другого потока до того, как объект был полностью построен. Поведение было недетерминированным, оно всегда работало на одноядерных процессорах и обычно работало на процессорах Intel, но в спешке падало на процессоры с более слабой моделью памяти, такой как Dec Alpha.

Тогда «безопасный контекст последнего поля» - это область кода, которая участвует в назначении вышеприведенному последнему полю (SINGLETON_ACCOUNT_TYPE), и он охватывает весь конструктор для AwesomeAccountType И код, внутренний для JVM для выделения и инициализации память для объекта.

Эти изменения в модели памяти Java были внесены в JSR133, следующий FAQ очень полезен для понимания контекста внесенных изменений: Часто задаваемые вопросы по JSR133.

person Chris K    schedule 09.09.2014
comment
Итак, мое предположение было неверным. Но я все еще смущен. В опубликованной вами ссылке на часто задаваемые вопросы JSR133 они упомянули правильно построенный объект. Могу ли я предположить, что объект был построен в контексте, безопасном для конечного поля, когда ни указатель на этот объект, ни указатель на его конечное поле не просочились во время строительства? Или я опять ошибаюсь? - person mkrakhin; 09.09.2014
comment
Почти «правильно сконструированный объект» относится к проблеме, при которой ссылка на объект ускользает в другой код до того, как объект будет полностью построен (или существует риск того, что это произойдет). Google для "проблем с двойной проверкой блокировок на Java". Дуг Ли написал несколько отличных статей, в которых подробно рассматриваются эти проблемы, и они легли в основу JSR 133. - person Chris K; 09.09.2014
comment
cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking. html является одним из таких примеров. Также стоит прочитать страницу в Википедии по этой теме. en.wikipedia.org/wiki/Double-checked_locking#Usage_in_Java - person Chris K; 09.09.2014
comment
Правильно построенные и правильно публикуемые ссылки на построенный объект - это связанные темы. И да, последнее поле может использоваться как часть этой публикации (после Java 5). Однако это не единственный способ сделать это и не гарантирует этого сам по себе. Например, конструктор, который вызывает метод, который может быть переопределен для объекта, который затем вызывает другой объект, не должен передавать ссылку, хранящуюся в 'this', из объекта, иначе он может публиковать объект, который еще не полностью построен. . - person Chris K; 09.09.2014