- Может ли кто-нибудь объяснить безопасность инициализации, как требуется моделью памяти Java?
- Как поля final помогают в обеспечении безопасности инициализации?
- Какую роль играет конструктор при обеспечении безопасности инициализации?
Пожалуйста, объясните безопасность инициализации, как указано в модели памяти Java
Ответ 1
Безопасность инициализации обеспечивает просмотр объекта внешним потоком в полностью сконструированном (инициализированном) состоянии. Предпосылкой является то, что объект не должен публиковаться преждевременно, т.е. в его конструкторе. Как только это будет обеспечено, JMM требует определенного поведения для полей, объявленных как final
. Во-первых, все поля объекта final
гарантируются внешним видимым внешним потоком в его полностью инициализированном состоянии - это не так тривиально, как кажется -
Рассмотрим класс
class A{
List list ;
A() {
list = Arrays.asList(some init expressions that adds 10 elements to list);
}
}
Поток, который обращается к экземпляру list
экземпляра A
, по умолчанию не гарантированно видит 10 элементов в этом списке. Фактически, этот поток даже может видеть list
как null
. Однако, если list
объявлен final
, тогда, как требуется JMM, list
всегда должен быть инициализирован с 10 элементами, которые он имеет.
Во-вторых, эта гарантия инициализации не ограничивается самим полем final
, но рекурсивно распространяется на все связанные с ней объекты. Например, если list
в приведенном выше примере представляет собой список list
, то внешний поток гарантированно будет видеть внутренние списки как полностью инициализированные.
Обратите внимание, что мы не используем synchronized
для достижения этой безопасности в видимости памяти (происходит до отношения).
Ответ 2
1. Безопасность инициализации позволяет правильно сконструировать неизменяемые объекты для безопасного обмена ими по потокам без использования синхронизации, независимо от того, были ли они опубликованы с использованием расы данных.
2. Объекты с конечным полем, безопасность инициализации предотвращают переупорядочение любой части конструкции с начальной загрузкой ссылки на этот объект.