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