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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 创造命运 中级黑马   /  2014-5-9 09:10  /  1767 人查看  /  7 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 创造命运 于 2014-5-9 16:04 编辑

正在复习,准备申请入学考试了。刚刚看到单例模式,有句话我怎么都理解不过来。请教大神们。
代码如下:
               class Single
               {
                                      private static Single s = null;
                                      private Single()
                                      {}                                                                 
                                      public static Single getInstance()
                                      {
                                                    //用双重判断来提高懒汉式的效率
                                                    if (s == null)
                                                    {
                                                                  synchronized(Single.class)  //锁是本类对应的字节码文件对象
                                                                  {
                                                                                if (s == null)
                                                                                               s = new Single();
                                                                   }
                                                    }
                                                    return s;
                                     }
                }


毕老师说用双重判断可以解决效率低的问题,刚开始学的时候,还没怎么注意。可刚刚复习到这,怎么也理解不过来了。再看视频也是不怎么理解。哪位大神能说的更通透一点的,谢啦。

评分

参与人数 1技术分 +1 收起 理由
张然龙 + 1

查看全部评分

7 个回复

正序浏览
透彻,谢谢啦
回复 使用道具 举报
楼上的回答非常详尽,受教了!
回复 使用道具 举报
要从单例的出现---->解决安全问题------>解决程序效率低问题,这三个问题理解单例(懒汉式),如果单纯看成熟的代码,会不容易理解...

单例设计模式目的是:类在内存中对象的唯一性!
  1. <blockquote>class Single
复制代码
//假设A,B两个线程并发访问getInstacne()方法,因为有多条语句操作共享数据s,一个在判断一个在赋值。
        //当线程A判断为null,此时A线程假设遇到sleep语句睡了一会。被线程B抢到执行权,
        //线程B进来也sleep了,A醒后创建一个对象赋给s,B醒了又创建个对象,
        //单例的目的要保证一个类在内存中对象的唯一性,new了很多对象,所以不安全
  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.                 return s;
  10.         }
  11. }
复制代码
//加上synchronized同步锁后,A线程进来,B线程进不来。当A线程new一个对象赋给s出去后,
        //B进来判断s不为null,就不new对象,直接返回s使用。这样就解决了安全问题
       
        //但是如果有n多线程并发访问getInstance()方法想获取实例,每次调用都要判断锁,
        //判断锁的次数会很多导致代码运行速度降低
  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.         }
  17. }
复制代码
//为了解决这个问题,采用双重判断的方式,
        //当A线程进来后,先判断s是否为空,如果为空在持有锁后可能sleep一会,B线程没有持有锁,不能进来
        //A线程醒后,new一个对象出去释放锁,B线程持有锁进来,判断st不为null,直接使用s,以后其他所有线程调用getInstance()方法,
        //判断s不为空,就直接使用s,这种方式锁只判断了一次,解决了程序运行低的问题






评分

参与人数 1技术分 +1 收起 理由
张然龙 + 1

查看全部评分

回复 使用道具 举报
  1. <font size="3"><span style="line-height: 24px;">/*</span></font>
复制代码


回复 使用道具 举报
  1. /*
  2. 懒汉式,对象是方法被调用时,才初始化,也叫做对象的延时加载
  3. */
  4. class Student{
  5.         /
  6.         private Student(){}        //单例设计三步骤1.将构造函数私有化
  7.         private  static Student s = null;        //2.在类创建一个私有静态的本类对象(懒汉式为null,方法被调用时才创建)
  8.         public static Student getInstance(){        //3.提供一个公有静态方法获取该类对象。
  9.                
  10.                 if(s==null){        //只要有一个线程初始化,s的值不为空,后面所有的线程都不需要再判断锁。
  11.                         synchronized(Single.class){//锁是该方法所在类的字节码文件
  12.                                 if(s==null){
  13.                 //                        A-->;B--> 加synchronized可避免多线程创建多个对象。
  14.                                         s = new Student();
  15.                                 }
  16.                                
  17.                         }
  18.                 }
  19.                 return s;
  20.         }
  21.        
  22. }
复制代码
再复习一下毕老师83和140两个视频,应该能理解。

评分

参与人数 1技术分 +1 收起 理由
张然龙 + 1

查看全部评分

回复 使用道具 举报
额,学习了。。。这个我也是不理解。同学,你技术分怎么来的那么多?
回复 使用道具 举报
  1. class Single
  2.                {
  3.      private static Single s = null;
  4.      private Single(){}                                                                 
  5.      public static Single getInstance()
  6.     {
  7.      //用双重判断来提高懒汉式的效率
  8.             if (s == null)
  9.             {
  10.                    synchronized(Single.class)  //锁是本类对应的字节码文件对象/<font color="#ff0000">/锁是一个消耗品,毕老师的意思就是为了避免每次线程进来都跑一次锁。</font>
  11.                    {
  12.                             if (s == null)<font color="#ff0000">//例如这里开了好几个个线程,第一个线程进来后new了一个对象后,就不再为空,外面那个判断就可以把其他线程挡在外面了,这样就可以提高效率啦,但要注意的是,先进来那个线程有可能在new对象前会被抢掉执行权,但锁没释放,其他的也进不来。希望你能明白,祝好运!</font>
  13.                             s = new Single();
  14.                    }
  15.            }
  16.            return s;
  17.    }
  18.                 }
复制代码


评分

参与人数 1技术分 +1 收起 理由
SyouRai_Tsk + 1

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马