To prove initialization safety for immutable objects, I wrote a small program. Even though fields were final, second thread was able to view the half-constructed object being created by the first thread. Have I got the concept wrong or "object escaping" can cause it? Second thread first printed "10 null" and then after half of the iterations it started printing "10 apple".
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++;
}
}
}
final
fields are guaranteed to have been initialized when the contructor call finishes. Naturally, a "leaking this" will subvert the value of this guarantee:
globalList.add(this); // ObjectEscape.<init> has not finished yet
See also: Java leaking this in constructor
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With