对于圆形immutables:
class Foo
{
final Object param;
final Foo other;
Foo(Object param, Foo other)
{
this.param = param;
this.other = other;
}
// create a pair of Foo's, A=this, B=other
Foo(Object paramA, Object paramB)
{
this.param = paramA;
this.other = new Foo(paramB, this);
}
Foo getOther(){ return other; }
}
// usage
Foo fooA = new Foo(paramA, paramB);
Foo fooB = fooA.getOther();
// publish fooA/fooB (unsafely)
的一个问题是,由于fooA
this
是内部构造泄露,是fooA
仍然是线程安全的不可变的?也就是说,如果另一个线程读取fooB.getOther().param
,它是否保证看到paramA
?答案是肯定的,因为this
在冻结动作之前没有泄露给另一个线程;我们可以建立规范所需的hb/dc/mc命令来证明paramA
是读取的唯一可见值。
回到你原来的问题。在实践中,总是有一些限制超出了纯技术的限制。考虑到所有工程,运营,政治和其他人为原因,初始化构造函数中的所有内容并不一定是设计的最佳选择。
有没有想过为什么我们会觉得这是一个伟大的最高想法?
更深层的问题是Java 缺少安全出版物的一般廉价fense比易失性便宜。 Java只有它的final
字段;出于某种原因,该围栏不可用,否则。
现在final
有两个独立的含义:第一,最后一个字段必须分配一次; 2,安全发布的内存语义。这两个含义与彼此无关。将它们捆绑在一起是相当混乱的。当人们需要第二个含义时,他们也被迫接受第一个含义。当第一个设计很不方便时,人们会问他们做了什么错误 - 没有意识到是Java做错了。
将一个final
下的两个含义捆绑在一起使它成为双加好的,所以显然我们有更多的理由和动机来使用final
。更险恶的故事实际上是我们被迫使用它,因为我们没有给予更灵活的选择。
此方法的任何示例可用? – user77115 2016-08-23 06:52:55