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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 吴华二 中级黑马   /  2012-3-27 00:46  /  2983 人查看  /  7 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

在听了单例模式那一小节时,突然有一个小的想法,单例设计模式中懒汉式和饿汉式之间有什么不同?有必要区分这两形式吗?本人认为区分这两种形式没必要,都是不管调用多少次getInstance方法,返回的都是同一个实例对象。如果要区分,它们之间有什么好处呢?什么情况下用懒汉式?什么情况又用饿汉式呢?求解...

7 个回复

正序浏览
抓哇 初级黑马 2012-3-28 10:34:03
8#
迷惑了 都是说饿汉式好 那懒汉式有哪里好 整他出来做什么 仅仅是延伸出 延长加载的概念吗
回复 使用道具 举报
王思兰 黑马帝 2012-3-27 23:09:57
7#
  单例模式 保证一个类仅有一个实例,并提供一个访问它的全局访问点;

       1、只能有一个实例对象,所以构造函数要私有化,

       2、私有化后,外部不能新建对象,在内部新建一个本类对象,

       3、并且在本类里提供一个可供外部访问的静态方法getInstance(),一开始就要被加载。

      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;
               }
       }这种被称为懒汉式,对象在方法调用时才初始化,也叫做对象的延迟加载,Single类进内存,对象没建立,只有调用了getInstance方法时,才建立对象,多线程用不安全,可以在getInstance加上synchronized同步,但是效率就低了,可以在if判断语句外部在加一个判断,这样就不用,每次都加锁,
               public static Single getInstance()
               {
                       if(s==null)
                        {

                               synchronized(Single.class)

                                                    {

                                                                         if(s==null)
                                                   s = new Single();

                                                    }

                        }

                       return s;
               }

回复 使用道具 举报

饿汉式:
这个是先初始化对象,Single类一进内存,就已经创建好了对象。 语句简单,线程安全。效率高
class Single
{
        private Single(){}
        private static Single s = new Single();
        public static Single getInstance()
        {
                return s;
        }
}

懒汉式:对象是方法呗调用时,才初始化。也叫做对象的延时加载。
Single类进内存,对象还没有存在,只有调用了getInstance方法是,才建立对象。线程不安全,得使用sychronized  线程安全,并进行双判断使效率提高

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;
        }

}

综上所述:定义单例,建议使用饿汉式,懒汉式在面试的时候能说出来就可以了。
回复 使用道具 举报
饿汉式是类加载后就创建一个对象,且线程是安全的;
懒汉式是在调用时才创建该类对象,由于在多线程访问时懒汉式可能会出现创建出多个实例,会出现安全问题,进而对其使用synchronized进行加锁,这样做降低程序的执行效率和降低程序的性能。
所以,建议使用饿汉式
回复 使用道具 举报
借用下一楼的代码:饿汉式:
   public class Singleton{
   private static Singleton singleton = new Singleton ();
   private Singleton (){}
   public Singleton getInstance(){return singletion;}
   }  

  懒汉式:
   public class Singleton{
   private static Singleton singleton = null;
   public static synchronized synchronized getInstance(){
   if(singleton==null){
   singleton = new Singleton();
   }
   return singleton;
   }
   }  
饿汉式就是在类加载的时候就创建一个对象,以后不再重复创建,并且线程安全。
懒汉式请看这里:
if(singleton==null){
   singleton = new Singleton();
如果有两个线程,第一个运行if的时候满足条件但是需要休息一下,而第二个线程又进来了,执行if语句仍然满足,于是创建对象,第一个醒来后又创建了对象,就创建两个对象了,所以不安全,建议使用第一种!
回复 使用道具 举报
懒汉式  是只要你不调用该类中的getInstance 方法  他就不会创建对象,只有在调用这个方法的时候才会创建该类对象   
            还有就是 懒汉是 线程不安全   需要加锁 让其同步
  饿汉式  是不管你调用不调用getInstance方法  它都会创建该类对象,  而这个线程安全  
虽然两个创建对象有所不同 但是因为都是静态的  不管怎么样 这个东西都会加载到内存的   所以一般还是推荐使用饿汉式     
回复 使用道具 举报
饿汉式:
  public class Singleton{
  private static Singleton singleton = new Singleton ();
  private Singleton (){}
  public Singleton getInstance(){return singletion;}
  }  

  懒汉式:
  public class Singleton{
  private static Singleton singleton = null;
  public static synchronized synchronized getInstance(){
  if(singleton==null){
  singleton = new Singleton();
  }
  return singleton;
  }
  }  

  比较:
  饿汉式是线程安全的,在类创建的同时就已经创建好一个静态的对象供系统使用,以后不在改变
  懒汉式如果在创建实例对象时不加上synchronized则会导致对对象的访问不是线程安全的
  推荐使用第一种  
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马