填坑关于线程在构造函数里中断后是否会形成竞态条件,看《Java并发编程实战》的一个疑问

在看《Java并发编程实战》一书的40页和41页时产生了一个疑问,作者说采用了不可变对象会使这个程序保持线程安全,但是我想了一下发现点问题。

源代码我就懒得打出来了,照两张相吧



现在假如有两个线程A和B,A线程先进行,当A线程访问到

cache = new OneValueCache(i, factors);

然后进入OneValueCache的构造函数,假如线程A在下面代码的第一句后中断了,像下面那样(故意插入一个sleep()让它中断)。

lastNumber = i;
Thread.sleep(1000);
lastFactors = Arrays.copyOf(factors, factors.length);

此时的成员变量cache已经被线程A更改成了一个半初始化的新变量(lastNumber已经被初始化值,但是lastFactors还没初始化,值为初始值null)<这句话是错的,下面分析>。

这时线程B获取cpu执行权,然后访问service()函数,当线程B访问到

BigInteger[] factors = cache.getFactors(i);

此时线程B访问了一个半初始化的成员变量cache,不会产生错误?

这个问题我想了很久,写了很多demo测试,最后发现是我想错了,线程B执行的是原来的cache,cache的值并没有被线程A修改,因为要等到构造函数彻底完成后才会返回this引用,成员变量cache才会更新,所以不用考虑构造函数里面赋值的原子性。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值