Каково точное значение конечного безопасного поля в JLS?

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

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

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

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 FAQ.

Другие вопросы по тегам