黑马程序员技术交流社区

标题: 单例设计模式的两种实现疑问 [打印本页]

作者: 李深山    时间: 2012-3-20 23:04
标题: 单例设计模式的两种实现疑问
单例设计模式中的“懒汉式”和“饿汉式”是怎么区分的,具体使用上有什么说道?我总是搞蒙。
作者: 叶绍亮    时间: 2012-3-20 23:08
饿汉式是线程安全的,在类创建的同时就已经创建好一个静态的对象供系统使用,以后不在改变.
懒汉式如果在创建实例对象时不加上synchronized则会导致对对象的访问不是线程安全的.
作者: 田斌    时间: 2012-3-20 23:16
毕老师的例子,很好记,区别就是饿汉式需要判断
单例设计模式:
饿汉式:
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.加同步的时候使用的锁是哪一个?
        该类所属的字节码文件对象

作者: 朱鹏举    时间: 2012-3-20 23:16
先初始化对象。称为:饿汉式。
对象是方法被调用时,才初始化,也叫做对象的延时加载。称为:懒汉式
记录原则:定义单例,建议使用饿汉式
饿汉式如下:
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;
        }
}

作者: 田斌    时间: 2012-3-20 23:17
第二个例子是懒汉式,sorry
作者: 李深山    时间: 2012-3-20 23:20
嗯,田斌介绍的不错,看着有点眉目
作者: OMG    时间: 2012-3-21 00:07
本帖最后由 OMG 于 2012-3-21 00:13 编辑

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

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

作者: 朱亚安    时间: 2012-3-21 02:24
  饿汉式单例类

//饿汉式单例类.在类初始化时,已经自行实例化
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则会导致对对象的访问不是线程安全的;





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2