Чтобы доказать безопасность инициализации для неизменяемых объектов, я написал небольшую программу. Несмотря на то, что поля были окончательными, второй поток смог просмотреть полуконструированный объект, создаваемый первым потоком. Есть ли у меня неправильная концепция или «побег объекта» может вызвать ее? Второй поток сначала напечатал «10 null», а затем после половины итераций он начал печатать «10 яблоко».Java гарантирует безопасность инициализации для неизменяемых объектов?
package test;
import java.util.ArrayList;
import java.util.List;
public final class ObjectEscape implements Runnable {
private final int a;
private final String b;
//this list is defined somewhere else
public static volatile List<ObjectEscape> globalList = new ArrayList<ObjectEscape>();
public ObjectEscape() throws InterruptedException {
a = 10;
globalList.add(this);
Thread.sleep(10);
b = "apple";
System.out.println("done");
}
public ObjectEscape(int a) {
this.a = 1;
b = "";
}
public static void main(String are[]) throws InterruptedException{
Thread t = new Thread(new ObjectEscape(1));
t.start();
ObjectEscape oe1 = new ObjectEscape();
}
@Override
public void run() {
int i=0;
while(i<10) {
if(globalList.get(0) != null)
System.out.println(globalList.get(0).a+" "+globalList.get(0).b);
i++;
}
}
}
Коллекция не поточно, и нет никакой гарантии, что поток не будет а) начать долго после добавления объекта или b) закончить задолго до того, как вы добавите объекты. Вы должны помнить, что нить может начать работать и умереть менее чем за 100 микросекунд. –
@PeterLawrey Я полностью согласен, я просто хотел доказать свою точку зрения. Не могли бы вы прокомментировать комментарий, который я сделал на ответ Павла? – Abidi