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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 李深山 中级黑马   /  2012-3-20 23:04  /  2272 人查看  /  7 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

单例设计模式中的“懒汉式”和“饿汉式”是怎么区分的,具体使用上有什么说道?我总是搞蒙。

7 个回复

倒序浏览
饿汉式是线程安全的,在类创建的同时就已经创建好一个静态的对象供系统使用,以后不在改变.
懒汉式如果在创建实例对象时不加上synchronized则会导致对对象的访问不是线程安全的.
回复 使用道具 举报
毕老师的例子,很好记,区别就是饿汉式需要判断
单例设计模式:
饿汉式:
class Single
{
     private static final 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)
         {
             synchronized(Single.class)
             {
                if(s==null)
                s = new Single();
             }
         }
         return s;
      }
}

毕老师说的面试问题:
1.懒汉式和饿汉式有什么不同?
        懒汉式的特点在于实例的延迟加载
2.懒汉式的延迟加载有没有问题?怎么解决?
        有,如果多线程访问时会出现安全问题,可以加同步来解决,
        用同步代码块和同步函数都行,但是稍微有点低效,用双重判断的形式可以解决这个问题
3.加同步的时候使用的锁是哪一个?
        该类所属的字节码文件对象

评分

参与人数 1技术分 +1 收起 理由
房宝彬 + 1

查看全部评分

回复 使用道具 举报
先初始化对象。称为:饿汉式。
对象是方法被调用时,才初始化,也叫做对象的延时加载。称为:懒汉式
记录原则:定义单例,建议使用饿汉式
饿汉式如下:
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;
        }
}
回复 使用道具 举报
第二个例子是懒汉式,sorry
回复 使用道具 举报
嗯,田斌介绍的不错,看着有点眉目
回复 使用道具 举报
OMG 中级黑马 2012-3-21 00:07:29
7#
本帖最后由 OMG 于 2012-3-21 00:13 编辑

两者的本质区别是
1,设计思路不同:
    A,为了方便,直接静态建立对象,并提供静态方法直接获取该对象;饿汉式
    B,为了节省内存,等到其他对象需要是再建立实例对象,也是只是声明一个空对象,在对外提 供获取对象的方法中,进行判断对象是否为空,为空就创建对象;懒汉式
2,应用优势不同:
    A,饿汉式在建立对象方面效率高,这对运行效率的提高有帮助;
    B,懒汉式在内存节约上有优势,因为是用的时候才建立对象占内存,但是有判断对象是否为空和建立对象两个独立语句,为多线程的安全隐患创造了条件;

总结:因为需求不同,所以会分类,但通常情况下,我们会使用饿汉式,因为简单,快,没有重复判断过程;
回复 使用道具 举报
  饿汉式单例类

//饿汉式单例类.在类初始化时,已经自行实例化
public class Singleton1 {
    //私有的默认构造子
    private Singleton1() {}
    //已经自行实例化
    private static final Singleton1 single = new Singleton1();
    //静态工厂方法
    public static Singleton1 getInstance() {
        return single;
    }
}


懒汉式单例类

//懒汉式单例类.在第一次调用的时候实例化
public class Singleton2 {
    //私有的默认构造子
    private Singleton2() {}
   
    //注意,这里没有final   
    private static Singleton2 single;
   
    //只实例化一次
    static{
        single = new Singleton2();
    }
   
    //静态工厂方法
    public synchronized  static Singleton2 getInstance() {
         if (single == null) {  
             single = new Singleton2();
         }  
        return single;
    }
}
饿汉式与懒汉式的区别:
饿汉式是线程安全的,在类创建后,加载时就会创建好一个静态的对象供系统使用,以后不在改变;懒汉式如果在创建实例对象时不加上synchronized则会导致对对象的访问不是线程安全的;
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马