返回信息流DCL是为了防止多线程访问时会造成的多次创建实例,导致单例模式失效。那DCL失效后,有没有公认的代替方案呢?
我查到一个
http://m.blog.itpub.net/28912557/viewspace-762047/
说的2个方案,总觉得不太理想~
附DCL(double check lock)定义:
public class InstanceHolder{
private static Instance ins = null;
private Instance(){}
public static Instance getInstance(){
if(ins == null){
synchronized(InstanceHolder.class){
//第二个线程进来时,有可能第一个线程已经创建了ins,所以再判断一次
if(ins == null){
ins = new Instance();
}
//第一个线程有可能在锁释放之前,刷新了主内存数据,导致第二个线程获取到的ins不为null
}
}
return ins;
}
这是一条镜像帖。来源:北邮人论坛 / java / #54061同步于 2016/11/23
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Java机器人发帖
单例用到的DCL失效后怎么解决的
echojessicaa
2016/11/23镜像同步3 回复
订阅后,新回复会通过你的通知中心匿名送达。
3 条回复
多谢~
另外,在实际应用中,如果初始化直接create实例,像这样
public class InstanceHolder {
private static InstanceHolder holder = new InstanceHolder();
private InstanceHolder (){
}
public static InstanceHolder getInstance(){
return holder;
}
而不是用volatile 加DCL的话,虽然在初始化的时候费些内存,但这更没有隐患吧,至于耗费的那点内存在实际应用应该是不予考虑的吧?
总结下我的猜想,如果是那种存在大量单例(比如数量级超过3位数了)的project,用volatile加DCL
如果单例较少,用上面那种在初始化时创建的方式就可以了。
不知道这个猜想是否成立呢?
【 在 nuanyangyang 的大作中提到: 】
: https://bbs.byr.cn/#!article/Java/52548
你想多了,只要有那个synchronized语句,就不会创建超过一个实例。不加volatile真正的危险是,别的线程有可能会观察到对象已经创建了(ins != null),但是对象的内容却是空的(实际上构造函数已经执行完了,但别的线程却还没有看到构造函数写入的内容)。
【 在 echojessicaa 的大作中提到: 】
: 多谢~
: 另外,在实际应用中,如果初始化直接create实例,像这样
: public class InstanceHolder {
: ...................