发布不可变

时间:2013-12-10 17:20:47

标签: java concurrency

可以通过任何机制发布不可变对象 - 必须安全地发布有效的不可变对象(静态初始化,易失性等) - “Java Concurrency in practice”。

class A{//immutable
    final int i;
    a(int i){
        this.i=i;
    }
    public int getI(){
        return i;
    }
} 

class B{
    A a=null;
    public A getA(){
       if(a==null){ 
           a= new A(10);
       }
       return a;
   }
}

如果在线程之间共享B的实例;不会有部分构造的A泄漏的可能性 - 尽管它是不可变的。
或者我明白这个错了吗?

1 个答案:

答案 0 :(得分:1)

A将被正确构造,因为它的所有字段都是最终的。你遇到的问题是getA()存在竞争条件,因为它是懒惰的,但不是线程安全的。即,不同的线程可以调用它并返回不同的对象。对象将是完整和正确的,但不是可能是意图的相同对象。请考虑以下

T1: if (a == null)
T2: if (a == null)
T3: if (a == null)
T1:     a = new A();
T1: return a;
T2:     a = new A();
T2: return a;
T3:     a = new A();
T3: return a;

所有三个线程都返回一个不同的对象。