黑马程序员技术交流社区

标题: 关于单例设计模式当中懒汉式线程的疑问 [打印本页]

作者: 陈佳    时间: 2015-1-11 13:06
标题: 关于单例设计模式当中懒汉式线程的疑问
以下是毕向东老师视频教程中关于单例设计模式的懒汉式的代码
  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啊,直接创建对象就好了。





作者: kerner    时间: 2015-1-11 14:51
如果第一个线程进入到第一个if代码块,此时并还没获取锁,此时虚拟机切换给第二个线程,它也进来了if代码块,并且同时获取锁,new一个对象,然后返回。接着虚拟机切换给第一个线程,它这时候才获取锁,此时如果没有第二个if判断,就会再new 一个对象。。。这就不能保证类的对象唯一性。
作者: 常尚全    时间: 2015-1-11 14:52
那个我刚好看完,后面会有解读,[[此处为何还要再次判断s是否为null?]]主要是懒汉模式的问题出现在:假如CPU执行到一半去执行别的地方了,就容易出现问题。用锁synchronized判断的话,防止出现这种问题,如果再详细的话,请看多线程哪里,会有解读。
建议用饿汉式
简译:懒汉考,饿汉用
作者: lwj123    时间: 2015-1-11 15:07
这是我分析的,你看看对你有没有帮助。

作者: 以利亚    时间: 2015-1-11 16:08
感谢分享,很有帮助!!
作者: 陈佳    时间: 2015-1-11 20:01
感谢各位的解答!!:handshake
作者: 陈佳    时间: 2015-1-13 10:45
kerner 发表于 2015-1-11 14:51
如果第一个线程进入到第一个if代码块,此时并还没获取锁,此时虚拟机切换给第二个线程,它也进来了if代码块 ...

明白了,感谢细心解答!
作者: vermouth    时间: 2015-1-13 11:16
自己心里懂 一直说不出来 看到楼上的解答 妥妥的学习了
作者: lovejjfg    时间: 2015-1-13 11:53
多线程那里就会强调懂起的!:handshake




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