Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java guarantees initialization safety for immutable objects?

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++;
        }
    }
}
like image 374
Abidi Avatar asked Jan 12 '23 07:01

Abidi


1 Answers

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

like image 192
Paul Bellora Avatar answered Jan 14 '23 21:01

Paul Bellora