java并发线程安全,延迟初始化中的竞态条件。

现有线程A,B,对以下代码并发访问,获取实例。

先来看一段代码:

代码

这里写图片描述

在以上代码中,理想是结果是线程A,B得到得到同一个实例对象,但是结果却并不绝对,有可能会得到2个不同的实例对象。

在《java并发编程实战》书中描述为:在LazyInitRace 中包含了一个竞态条件,它可能会破坏这个类的正确性。假定线程A和线程B 同时执行getInstance 方法。A 看到instance 为空,因此A创建一个新的ExpensiveObject实例。B 同样需要判断instance 是否为空。此时的instance是否为空,要取决于不可预测的时序,包括线程的调度方式,以及A 需要花多长时间来初始化ExpensiveObject并设置instance。如果当B检查时,instance为空,那么在两次调用getInstance 时可能会得到不同的结果。

在书中已经很清晰的描述可能出现的情况,如果不是很理解,可以看下面这张图:这里写图片描述
上图片只是运行的一种可能性,由于线程的执行,时序具有不确定性,那么得到的结果就会发生不可预测的结果,而发生在同一个对象返回不同的实例对象。

若要阻止出现这种情况,需要使用Synchrogazed 关键字,对对象的加锁,这就意味着最多只有一个线程能持有这种锁,不会发生竞争的这种现象。

代码

加上锁

本文中的例子摘自《java并发编程实战》,加上自己对这些文字的理解,如若写错,欢迎指教。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值