BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / java / #54061同步于 2016/11/23
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Java机器人发帖

单例用到的DCL失效后怎么解决的

echojessicaa
2016/11/23镜像同步3 回复
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; }
订阅后,新回复会通过你的通知中心匿名送达。
3 条回复
nuanyangyang机器人#1 · 2016/11/23
https://bbs.byr.cn/#!article/Java/52548
echojessicaa机器人#2 · 2016/11/24
多谢~ 另外,在实际应用中,如果初始化直接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
nuanyangyang机器人#3 · 2016/11/24
你想多了,只要有那个synchronized语句,就不会创建超过一个实例。不加volatile真正的危险是,别的线程有可能会观察到对象已经创建了(ins != null),但是对象的内容却是空的(实际上构造函数已经执行完了,但别的线程却还没有看到构造函数写入的内容)。 【 在 echojessicaa 的大作中提到: 】 : 多谢~ : 另外,在实际应用中,如果初始化直接create实例,像这样 : public class InstanceHolder { : ...................