Если бы другой поток проверял переменную someObject
"во время" построения, я полагаю, что может (из-за причуд в модели памяти) увидеть частично инициализированный объект. Новая (начиная с Java 5) модель памяти означает, что любые поля final должны быть установлены в их значения, прежде чем объект станет видимым для других потоков (если ссылка на вновь созданный объект не исчезает) от конструктора любым другим способом), но кроме этого, не так много гарантий.
По сути, не делитесь данными без соответствующей блокировки (или гарантий, предоставляемых статическими инициализаторами и т. Д.) :) Серьезно, модели памяти очень сложны, как и программирование без блокировок в целом. Постарайтесь не допустить, чтобы это стало возможным.
В логических терминах присваивание происходит после запуска конструктора - поэтому, если вы наблюдаете переменную из того же потока , она будет нулевой во время вызова конструктора , Однако, как я уже сказал, есть странности в модели памяти.
РЕДАКТИРОВАТЬ: В целях двойной проверки блокировки вы можете обойтись без этого , если ваше поле равно volatile
и , если вы используете Java 5 или выше. До Java 5 модель памяти была недостаточно сильной для этого. Вы должны правильно получить шаблон точно . См. Effective Java, 2nd edition, item 71, для получения более подробной информации.
РЕДАКТИРОВАТЬ: Вот мои аргументы против того, чтобы Аарон был видимым в одной теме. Предположим, у нас есть:
public class FooHolder
{
public static Foo f = null;
public static void main(String[] args)
{
f = new Foo();
System.out.println(f.fWasNull);
}
}
// Make this nested if you like, I don't believe it affects the reasoning
public class Foo
{
public boolean fWasNull;
public Foo()
{
fWasNull = FooHolder.f == null;
}
}
Я полагаю, что это будет всегда отчет true
. С раздел 15.26.1 :
В противном случае необходимо выполнить три шага:
- Сначала левый операнд вычисляется для создания переменной. Если эта оценка завершена
внезапно, то назначение
Выражение завершается внезапно для
та же самая причина; правый операнд
не оценивается и не присваивается
происходит.
- В противном случае вычисляется правый операнд. Если это
оценка завершается внезапно, затем
выражение присваивания завершается
внезапно по той же причине и нет
назначение происходит.
В противном случае значение правой руки
операнд преобразуется в тип
левая переменная, подвергается
преобразовать набор значений (§5.1.13) в
соответствующий стандартный набор значений
(не набор значений расширенного показателя),
и результат преобразования
сохраняется в переменной.
Затем из раздел 17.4.5 :
Два действия могут быть упорядочены с помощью отношения «до того». Если одно действие происходит раньше другого, то первое видно и упорядочено до второго.
Если у нас есть два действия x и y, мы пишем hb (x, y), чтобы указать, что x происходит до y.
- Если x и y являются действиями одного потока и x предшествует y в программном порядке, то hb (x, y).
- Для этого объекта существует крайний случай "до" от конца конструктора объекта до начала финализатора (§12.6).
- Если действие x синхронизируется со следующим действием y, то у нас также есть hb (x, y).
- Если hb (x, y) и hb (y, z), то hb (x, z).
Следует отметить, что наличие отношений между двумя
действия не обязательно подразумевают, что они должны происходить в таком порядке в
реализация. Если изменение порядка дает результаты, соответствующие юридическому исполнению,
это не незаконно.
Другими словами, вполне нормально, что странные вещи случаются даже в пределах одного потока , но это не должно наблюдаться . В этом случае разница будет заметной, поэтому я считаю, что она будет незаконной.