黑马程序员技术交流社区

标题: 懒汉式的效率问题 [打印本页]

作者: 王鑫    时间: 2013-6-4 15:24
标题: 懒汉式的效率问题

我们知道,为了解决懒汉式的安全问题,加上了同步代码块synchronized。

加上synchronized后降低了程序的效率,于是加上双重判断if(s==null)

问题来了,前者是线程进入时在Single.class处判断状态值是否为开,后者是线程进入时在if处判断s是否为空。
同样都是每个进程进入时做一次判断,何以后者就比前者高效了呢?


作者: 闫月乐    时间: 2013-6-4 16:33
本帖最后由 闫月乐 于 2013-6-4 16:35 编辑

  1. <P> </P>
复制代码

  1. if(s==null)
  2. {
  3. //首先,哥们,你的同步关键字写错了,多了一个s
  4. synchronized(Single.class)
  5. {
  6. /*
  7. 额,我感觉没多一行代码,就要多一次执行(当然是同种功能的)
  8. 如果加上if(s==null),他会在s!=null的时候,之间跳过该判定语句
  9. 执行后续语句.而没有的话,会先进同步代码块,再去判断,我的感觉
  10. 好像有点效率低了
  11. 恩,之后,就是一般我们要写高效懒汉式的话,会在同步代码块中加入
  12. try语句,模拟临时故障,否则面试官问你你有没经过测试,咋知道你写
  13. 的程序安全了!所以,加上吧!为了面试!
  14. 加上之后,就更明白了吧!加上if(s==null)后,就不用去执行try了,try
  15. 里面是让线程进入休眠!更浪费时间!
  16. */
  17. try
  18. {
  19. Thread.sleep(100);
  20. }
  21. catch (Exception e)
  22. {
  23. }
  24. if(s==null)
  25. s=new single();
  26. }
  27. }

复制代码

作者: 王瀛    时间: 2013-6-4 16:51
你可以把synchronized这句话看成是一道门。

对于上面那种未采取双重判断的:当第一次调用对象后,门关上了,由于是第一次,所以s==null满足,Single的对象被引用拿走,拿走后门开了。后面如果又来个需要访问对象的,还得再一次通过这道门,如果是在多线程中,会有N多想要访问Single对象的,于是需要判断N次,这样效率就降低了。

而对于下面加了双重判断的,synchronized还可以看作是门,而外层的if判断可以看作是门外的“请勿打扰”或者“无人可进”的牌子。当第一次访问对象时,看到牌子上写着“无人可进”,于是进门(synchronized),由于符合s==null的条件,对象被引用拿走。拿走的同时,牌子就变成了“请勿打扰”(s!=null),所以后面再有要创建对象的看到了门外的牌子后,就直接掉头走了,不会等在门外,更不用再次判断了,这样就提高了效率




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2