黑马程序员技术交流社区

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

作者: 黄玉昆    时间: 2013-2-15 21:26
标题: 懒汉式的效率问题
本帖最后由 黄玉昆 于 2013-2-16 14:32 编辑

毕老师写的单例设计模式中的懒汉式的两个示例如下:
第一种:
  1. class Single
  2. {
  3.       private static Single s = null;
  4.       private Single(){}
  5.       public static Single getInstance()
  6.       {
  7.           if (s == null)
  8.           {
  9.                synchronized(Single.class)
  10.               {
  11.                    if (s == null)
  12.                         s = new Single();
  13.               }
  14.         }
  15.         return s;
  16. }
复制代码
第二种:
  1. class Single
  2. {
  3.         private static Single s = null;
  4.         private Single(){}
  5.         public static synchronized Single getInstance()
  6.         {
  7.                         if (s == null)
  8.                                 s = new Single();
  9.                 }
  10.                 return s;
  11.         }
  12. }
复制代码
毕老师说第一种的双重判断是可以提高效率的,因为可以减少判断锁的次数。但是对于第一种,每次也要判断s==null,也就是说不用每次判断锁了,还要判断s,这样的效率能提高多少呢?
还是锁判断锁比判断s要低效呢?

作者: 柴乔军    时间: 2013-2-15 22:06
你问的这个效率问题有些底层了,先不说这个,如果说,当线程数目非常多时,在很短的时间内,有很多个线程都要访问调用这个方法,可能会在同一时间有多个线程,进入了这个方法中去判断是否为null,但是如果把锁加在方法上,那首先要对其加锁,其他的线程可就要在外面等候了,只有一个线程能执行,那么效率的高低就非常明显了,效率的提升主要在于多线程上
作者: 范天成    时间: 2013-2-15 22:11
判断程序的效率,最终还是要看转换后提供给CPU执行的机器码的数量和指令操作类型。虽然看上去都是一个判断,但是判断锁最后生成的机器码数量远大于一条s==nul语句所生成的机器码的量,例如乘除法运算,大家都知道位移比*和/要快,虽然看上去都是一条语句,但是CPU内部执行这样的指令最快。应该是所得判断最终消耗的CPU资源要大于相等判断。
作者: 朱玉玺    时间: 2013-2-16 12:34
老黄你第一个模式没写全
作者: 黄玉昆    时间: 2013-2-16 12:38
朱玉玺 发表于 2013-2-16 12:34
老黄你第一个模式没写全

嘿嘿,还真是,不知道是哪里出的问题,总出这样的事。
作者: 李培根    时间: 2013-2-16 13:34
本帖最后由 李培根 于 2013-2-16 13:37 编辑
黄玉昆 发表于 2013-2-16 12:38
嘿嘿,还真是,不知道是哪里出的问题,总出这样的事。
  1. class Single{        
  2.       private static Single s1 = null;        
  3.       private Single(){}      
  4.       public static Single getInstance(){   
  5.             if(s1==null){//如果s1==null才会创建,每次都需要判断
  6.                   s1 = new Single();  
  7.             }            
  8.             return s1;
  9.       }
  10. }
复制代码
  1. class Single2{
  2.         private static Single2 s1 = null;
  3.         private Single2(){}
  4.         public static Single2 getInstance(){               
  5.                 if(s1==null){//如果不为null不需要判断锁直接返回s1,s1==null每次都需要判断,这样如果不为null就不用判断锁,会提高效率
  6.                         synchronized(Single2.class){
  7.                                 if(s1==null)
  8.                                         s1 = new Single2();                               
  9.                         }
  10.                 }
  11.                 return s1;
  12.         }
  13. }
复制代码

作者: 黄玉昆    时间: 2013-2-16 14:32
李培根 发表于 2013-2-16 13:34

:handshake
感谢啊
作者: 李培根    时间: 2013-2-16 14:36
黄玉昆 发表于 2013-2-16 14:32
感谢啊

客气啦:)
作者: 铿锵科技    时间: 2013-2-16 16:16
如果有N多线程调用该类的getInstance()方法懒汉式每次调用都要判断是否创建了实例,
如果有N多线程调用该类的getInstance()方法饿汉式每次调用直接反回实例,这个方式更为高效一点,只是在程序初始化的时候时间比懒汉式稍长一点,如果你的程序不是频繁启动(结束)的话,建议用饿汉式




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