Это пример от JCiP.Являются ли неизменяемые объекты иммунными к неправильной публикации?
public class Unsafe {
// Unsafe publication
public Holder holder;
public void initialize() {
holder = new Holder(42);
}
}
public class Holder {
private int n;
public Holder(int n) {
this.n = n;
}
public void assertSanity() {
if (n != n) {
throw new AssertionError("This statement is false.");
}
}
}
На странице 34:
[15] Проблема здесь не сам держатель класса, но что держатель не правильно опубликован. Тем не менее, Владелец может быть застрахован до ненадлежащей публикации, объявив n поле окончательным, что сделает Holder неизменным;
И от this answer:
спецификация для окончательного (см @ ответ andersoj в) гарантирует, что при возврате конструктора, окончательное поле было правильно инициализируется (как видно из всех потоков) ,
От wiki:
Например, в Java, если вызов конструктора имеет были встраиваемым то общие переменным могут быть немедленно обновляются один раз хранилище было выделено, но до встраиваемых конструктора инициализирует объект
Мой вопрос:
Потому что: (может быть неправильно, я не знаю.)
а) общие переменное может быть немедленно обновлен до встраиваемого конструктор инициализирует объект.
b) окончательное поле будет гарантированно правильно инициализировано (как видно из всех потоков) ТОЛЬКО при возврате конструктора.
Возможно ли, что другой поток видит значение по умолчанию holder.n
? (т. е. другой поток получает ссылку на holder
до того, как возвращается конструктор holder
.)
Если да, то как вы объясните это утверждение ниже?
держатель может быть сделан невосприимчивым к неправильной публикации, объявив поле п , чтобы быть окончательными, что сделало бы держатель неизменного
EDIT: От JCiP.Определение неизменного объекта:
Объект является неизменным, если:
х его состояние не может быть изменен после строительства;х Все его поля являются окончательными; [12] и
х Это правильно построена (эта ссылка не избежать в процессе строительства).
Таким образом, по определению, неизменяемые объекты не имеют «this
ссылка« экранирование »проблем. Правильно?
Но будут ли они страдать от Out-of-order writes в шаблоне с двойной проверкой, если не объявлены изменчивыми?
Модель памяти Java гарантирует безопасную публикацию без явной синхронизации для всех неизменяемых объектов, поля экземпляров которых объявлены окончательными. – scottb
@scottb Неверный. Сам конструктор может утечка ссылки. – chrylis