A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 王鑫 中级黑马   /  2013-6-4 15:24  /  2060 人查看  /  2 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文


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

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

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

评分

参与人数 1技术分 +1 收起 理由
殇_心。 + 1

查看全部评分

2 个回复

倒序浏览
本帖最后由 闫月乐 于 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. }

复制代码
回复 使用道具 举报
你可以把synchronized这句话看成是一道门。

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

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