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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 秦松 中级黑马   /  2012-10-18 13:01  /  1850 人查看  /  10 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

问题:单例设计模式中的懒汉式与饿汉式分别有什么特点,以及各自的优缺点是什么,相同点与区别

评分

参与人数 1技术分 +1 收起 理由
韩军博 + 1

查看全部评分

10 个回复

正序浏览
lz你好,这是我总结的毕老师关于单例的讲解,希望对你有帮助。
****************************************************
1,单例模式存在的原因:为保证对象的唯一性,使一个类在内存中只存在一个对象。
2,单例模式的两种写法:
     饿汉式:
class Single
{
     private Single(){};
     private Single s = new Single();
     public static getSingle(){
              return s ;
     }
}
*****************
    懒汉式:
class Single
{
     private Single(){};
     private Single s = null;
     public static getSingle(){
                if(s==null)
                       s= new Single();            
                  return s ;
     }
}
3,两种模式的区别:简单说:开发用饿汉式,面试出懒汉式。
      饿汉式在jvm运行的时候已经创建好对象,不必考虑安全问题;
      懒汉式在第一次访问实例时才开始创建对象,需要同步。
     ps:csdn博客上的话,我总结不了这么好啊,不过记住了。
********************************
4,懒汉式同步的方法:
class Single
{
     private Single(){};
     private Single s = null;
     public static getSingle(){
                if(s==null)
                  synchronized(Single.class){
                       if(s==null)
                       s= new Single();            
                    
                   }
                      return s ;
     }
}  











回复 使用道具 举报
崔政 中级黑马 2012-10-18 23:32:44
10#
楼上那位仁兄比喻的十分恰当。
饿汉式是不管有人没人先做饭,懒汉式是有人吃再做饭。
饿汉式比较占用资源。

其实主要是毕老师说的那几个面试的经典问题。。
1.懒汉式和饿汉式有什么不同
        懒汉式的特点在于实例的延迟加载
2.懒汉式实例的延迟加载有没有问题?
        有,如果多线程访问时,会出现安全问题
3.怎么解决?
        加同步(锁)解决
4.怎么加?
        加同步代码块或同步函数都行。不过稍微有点低调,因为要判断
5.效率低怎么解决?
        用双层判断的方式可以解决
6.加同步的时候,使用的锁是哪一个?
        是该类所属的字节码文件对象
  1. //饿汉式
  2. /*class Single{
  3.         private static final Single s=new Single();
  4.         privagte Single(){}
  5.         public static Single getInstance(){
  6.                 return s;
  7.         }
  8. }/*

  9. //懒汉式
  10. class Single{
  11.         private Single s=null;
  12.         private Sinale(){}
  13.         public static Single getInstance(){
  14.                 if(s==null){
  15.                         synchronized(Single.class){
  16.                                 if(s==null)
  17.                                         s=new Single();
  18.                         }
  19.                 }
  20.                         return s;
  21.         }
复制代码
回复 使用道具 举报
廖智 中级黑马 2012-10-18 14:34:47
9#
本帖最后由 廖智 于 2012-10-18 14:38 编辑

恶汉式特点:类加载时不创建对象。
class Single
        {
                private static Single s = new Single();
                private Single(){}
                public static Single getInstance()//对数据进行可控。
                {
                        return s;
                }
        }
        懒汉式特点:类加载时不创建对象。会节省内存空间。
        class Single
        {
                private static Single s = null;
                private Single(){}
                public static Single getInstance()
                {
                        if(s==null)
                                s=new Single();
                        return s;

                }
        }
        开发时建议用饿汉式:
                1、因为写单例是要用对象,所以先加载和后加载没有区别。
                2、懒汉式会设计安全问题。
      在面试时一般会面试懒汉式,因为懒汉式设计了安全问题。
回复 使用道具 举报
廖智 中级黑马 2012-10-18 14:33:56
8#
本帖最后由 廖智 于 2012-10-18 14:40 编辑
王自强 发表于 2012-10-18 14:14
第一种体现:开发中用的多!
  1将该类的构造函数私有化,使外部不能调用该类的构造函数,只能该类的内部调 ...


   恩,赞同
      
回复 使用道具 举报
第一种体现:开发中用的多!
  1将该类的构造函数私有化,使外部不能调用该类的构造函数,只能该类的内部调用其构造函数。
  2在该类的内部自定义一个对象。
  3对外提供方法进行该唯一对象的获取。
  class demo//类一进内存,就已经创建好了对象。
  {
        private demo(){}
        private static demo d = new demo();//先初始化对象--饿汉式;
        public static demo getDemo()
        {
                return d;
        }

  }
第二种体现:面试较多!
  class demo//demo进内存,对象还没有存在,调用getDemo方法时,才创建对象。
  {
        private demo(){}
        private static demo d = null;//后初始化对象--懒汉式;
        public static demo getDemo()
        {
                if(d==null)
                synchronized(demo.class)
                {
                        if(d==null)
                                d = new demo();//对象是方法被调用时才初始化,也叫对象的延时加载。
                }
                return d;
        }

  }

评分

参与人数 1技术分 +1 收起 理由
韩军博 + 1 很给力!

查看全部评分

回复 使用道具 举报
曾浩 发表于 2012-10-18 13:12
单例模式-饿汉式:
     Class Person {
            Private Person(){}

:handshake
回复 使用道具 举报
单例设计模式是为了解决一个类在内存中只存在一个对象。
其实现方式就是在类中将构造方法私有化,并在类中自己创建一个本类对象,提供公有一个方法可获取到该对象。
当外界调用时,只能通过方法调用唯一的对象。
它分为:饿汉式和懒汉式。
这两种方式的主要区别是代码上的区别。
这个代码上的区别就是在类中自己创建一个本类对象的时机。
饿汉式就是不管外界有没有使用对象的要求,要先new一个对象让公有方法直接调用。
懒汉式是当外界调用公有方法时,才创建对象。
用个形象的比喻,就像是饭店做饭。饿汉式就表示不管有没有顾客要吃饭,先把饭做好。懒汉式表示等到有顾客点菜时在做饭。
实际开发中多使用饿汉式。懒汉式的做法有安全隐患,当出现多线程时,会出现违反单例模式的现象出现,也就是说出现两个本类对象。

评分

参与人数 2技术分 +1 黑马币 +2 收起 理由
韩军博 + 1
秦松 + 2 赞一个!

查看全部评分

回复 使用道具 举报
葬天 发表于 2012-10-18 13:10
懒汉模式,它的特点是运行时获得对象的速度比较慢,但加载类的时候比较快。它在整个应用的生命周期只有一部 ...

受教了:handshake
回复 使用道具 举报
单例模式-饿汉式:
     Class Person {
            Private Person(){}
                                Private static Person p = new Person();
        Private static Person getPerson(){
        Return p;
        }
}


懒汉式:
Class Person {
            Private Person(){}
                                Private static Person p = null;
        Private static Person getPerson(){
             If (p==null)
                 P = new Person();
        Return p;
        }
}

在多线程下 单例模式中的 懒汉式中的 get方法要用synchronized锁修饰 防止多个线程new多个对象 但是用synchronized同步方法这样效率低了点 可以用另一个方式:     因为方法是静态的所有锁是类名.class(这个类随便都可以只要是两个类都可以访问到)  可以用锁可控制代码块 不一定是函数 这个方式效率稍高
If(s==null){
Synchronized(Person.class){If(s==null){
S= new Person();}
}
}
回复 使用道具 举报
懒汉模式,它的特点是运行时获得对象的速度比较慢,但加载类的时候比较快。它在整个应用的生命周期只有一部分时间在占用资源。
饿汉模式,它的特点是加载类的时候比较慢,但运行时获得对象的速度比较快。它从加载到应用结束会一直占用资源。

评分

参与人数 1技术分 +1 收起 理由
韩军博 + 1 很给力!

查看全部评分

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