考虑从Java并发的片段在行为─一点澄清volatile关键字
// Unsafe publication
public Holder holder;
public void initialize(){
holder = new holder(42);
}
public class Holder{
private int n;
public Holder(int n) {
this.n = n;
}
public void assertSanity(){
if (n != n)
throw new AssertionError("This statement is false.");
}
}
一经书的作者提出的解决方案是 -
public static Holder holder = new Holder(42);
如果唯一的要求是防止AssertionError
,那么这也可以很好地工作 -
private final int n;
我的问题是后续的评论对这段计算器thread约翰Vint-
其实,宣告成员字段挥发性仍犯规保证 出版物持有者可见之前。您可以看看 ConcurrentHashMap的私有方法readUnderLock,其中考虑到了这个细微差别 。虽然宣称持有人是挥发性的。
说得简单的话,他特此提示2东西 -
public volatile Holder holder;
public void initialize(){
holder = new holder(42);
}
在上述解决方案将很好地工作?如果将引用声明为volatile,是否确保安全对象发布?数组也是对象。声明数组引用不会使其元素线程安全。
而且为什么由作者 -
public class Holder {
private volatile int n;
的建议,宣布成员字段挥发性仍犯规保障 公布持有人前,这是不行的可见
即使作为成员字段已被声明为volatile,其保证条件n != n
将始终为false,因此没有AssertionError
。请建议。
感谢。但是这个具体案例不是作者错误的。 –
@ShirgillFarhanAnsari我同意,一般来说'volatile'不提供你需要的保证,但在这种特定情况下,它会发生作用。 –
再次感谢,但没有得到您的第二个代码片段持有人h =持有人;//读屏障的观点。请详细说明。 –