java 安全发布_《java并发编程实战》安全发布?

3.5 安全发布

3.5.1 不正确的发布

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.");

}

}

由于没有使用同步来确保Holder对象对其他线程可见,因此将Holder称为“未被正确发布”。在未被正确发布的对象中存在两个问题。

① 首先,除了发布对象的线程外,其他线程可以看到的Holder域是一个失效值,因此将看到一个空引用或者之前的旧值。

② 然而,更糟糕的情况是,线程看到Holder引用的值是最新的,但Holder状态的值却是失效的。

③ 情况变得更加不可预测的是,某个线程在第一次读取域时得到失效值,而再次读取这个域时会得到一个更新值,这也是assertSainty抛出AssertionError的原因。

问题:注释中说“如果将n声明为final类型,就不会出现不正确发布的问题”。将n设为final类型,那①不是照样会发生吗?“除了发布对象的线程外,其他线程可以看到的Holder域是一个失效值,因此将看到一个空引用或者之前的旧值”,会得到旧值的呀。为什么不会出现不正确发布呢?

换句话说,书上说不可变对象在何时都是线程安全的。那么线程在初始化这个对象时,还未初始化完全,另一个线程就获取了这个对象的引用,这个时候引用是空的。这哪里安全了?

求大佬帮忙看下。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值