Vincent哥的博客

java,大数据

填坑关于线程在构造函数里中断后是否会形成竞态条件,看《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才会更新,所以不用考虑构造函数里面赋值的原子性。

阅读更多
个人分类: java
上一篇(填坑)关于spring 依赖注入的javaConfig和xml配置混合使用在junit测试中的测试失败。
下一篇虚拟机中centos7重启后网卡突然消失解决方法
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭