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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 陈佳 中级黑马   /  2015-1-11 13:06  /  1148 人查看  /  8 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

以下是毕向东老师视频教程中关于单例设计模式的懒汉式的代码
  1. class Single
  2. {
  3.          private static Single s = null;//此处不能加final
  4.          private Single(){}
  5.          public static Single getInstance()
  6.          {
  7.               if(s==null)
  8.                        s = new Single();
  9.               return s;
  10.          }
  11. }
复制代码
以下是加入了线程同步代码块,问题见单行注释。
  1. public static Single getInstance()
  2. {
  3. <p style="line-height: 30px; text-indent: 2em;"></p><p style="line-height: 30px; text-indent: 2em;"></p>       if(s==null)
  4.       {
  5.                synchronized (Single.class)//可以减少判断锁的次数,所以效率高
  6.                {
  7.                         if(s==null)//此处为何还要再次判断s是否为null?
  8.                               s = new Single();
  9.                }
  10.       }
  11.       return s;
  12. }
复制代码
如果在执行此代码时,s已经指向了实例,那么if代码块就不会执行,因此没有必要在其中再次判断s是否为null
如果在执行此代码时,s还没有指向实例,那么进入同步代码块后,也没有必要判断s是否为null,因为s此时必然为null啊,直接创建对象就好了。




8 个回复

倒序浏览
如果第一个线程进入到第一个if代码块,此时并还没获取锁,此时虚拟机切换给第二个线程,它也进来了if代码块,并且同时获取锁,new一个对象,然后返回。接着虚拟机切换给第一个线程,它这时候才获取锁,此时如果没有第二个if判断,就会再new 一个对象。。。这就不能保证类的对象唯一性。
回复 使用道具 举报
那个我刚好看完,后面会有解读,[[此处为何还要再次判断s是否为null?]]主要是懒汉模式的问题出现在:假如CPU执行到一半去执行别的地方了,就容易出现问题。用锁synchronized判断的话,防止出现这种问题,如果再详细的话,请看多线程哪里,会有解读。
建议用饿汉式
简译:懒汉考,饿汉用
回复 使用道具 举报
这是我分析的,你看看对你有没有帮助。
回复 使用道具 举报
感谢分享,很有帮助!!
回复 使用道具 举报
感谢各位的解答!!:handshake
回复 使用道具 举报
陈佳 中级黑马 2015-1-13 10:45:06
7#
kerner 发表于 2015-1-11 14:51
如果第一个线程进入到第一个if代码块,此时并还没获取锁,此时虚拟机切换给第二个线程,它也进来了if代码块 ...

明白了,感谢细心解答!
回复 使用道具 举报
自己心里懂 一直说不出来 看到楼上的解答 妥妥的学习了
回复 使用道具 举报
多线程那里就会强调懂起的!:handshake
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马