Java保证了不可变对象的初始化安全性?

时间:2013-09-22 19:58:40

标签: java multithreading

为了证明不可变对象的初始化安全性,我写了一个小程序。即使字段是最终的,第二个线程也能够查看由第一个线程创建的半构造对象。我有错误的概念或“对象逃逸”会导致它吗?第二个线程首先打印“10 null”,然后在一半的迭代后开始打印“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++;
        }
    }
}

1 个答案:

答案 0 :(得分:8)

当构造函数调用完成时,保证

final个字段已初始化。当然,“泄漏这个”将颠覆这种保证的价值:

globalList.add(this); // ObjectEscape.<init> has not finished yet

另请参阅:Java leaking this in constructor