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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 黄玉昆 黑马帝   /  2013-2-15 21:26  /  1848 人查看  /  8 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 黄玉昆 于 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要低效呢?

评分

参与人数 1黑马币 +9 收起 理由
李培根 + 9 赞一个!

查看全部评分

8 个回复

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

:handshake
感谢啊
回复 使用道具 举报
黄玉昆 发表于 2013-2-16 14:32
感谢啊

客气啦:)
回复 使用道具 举报
如果有N多线程调用该类的getInstance()方法懒汉式每次调用都要判断是否创建了实例,
如果有N多线程调用该类的getInstance()方法饿汉式每次调用直接反回实例,这个方式更为高效一点,只是在程序初始化的时候时间比懒汉式稍长一点,如果你的程序不是频繁启动(结束)的话,建议用饿汉式
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马