黑马程序员技术交流社区

标题: 求关于懒汉式单例设计模式的问题总结 [打印本页]

作者: zhangle    时间: 2014-4-17 12:44
标题: 求关于懒汉式单例设计模式的问题总结
本帖最后由 zhangle 于 2014-4-17 14:16 编辑

懒汉式单例设计模式中都有哪些可以问题可以被问到,求高手总结一下

作者: 天空之城°    时间: 2014-4-17 12:59
他和饿汉式有什么区别?
两种方案的构造函数和公用方法都是静态的(static),实例和公用方法又都是私有的(private)。但是饿汉式每次调用的时候不用做创建,直接返回已经创建好的实例。这样虽然节省了时间,但是却占用了空间,实例本身为static的,会一直在内存中带着。懒汉式则是判断,在用的时候才加载,会影响程序的速度。最关键的是,在并发的情况下,懒汉式是不安全的。如果两个线程,我们称它们为线程1和线程2,在同一时间调用getInstance()方法,如果线程1先进入if块,然后线程2进行控制,那么就会有两个实例被创建。

作者: tacyjay在路上    时间: 2014-4-17 13:11
本帖最后由 tacyjay在路上 于 2014-4-17 13:17 编辑

据毕老师视频上来说,懒汉式的问题主要在其的不安全性,可以参考下

写法一:初始化对象——饿汉式
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类一进内存,就已经创建好了对象。
懒汉式特点:Single类进内存,对象还没存在,只有调用了getInstance方法时,才建立对象。
开发时一般使用饿汉式方法,因为比较安全。
对于懒汉式可以用public static synchronized(同步,锁) Single getInstance ,不过效率会因而减慢。
可以继续改进为:
public static Single getInstance()
{
if (s == null)
{
synchronized(Single.class)
{
if (n == null)
s = new Single();
}
}
return s;
}
原则:定义单例,建议使用饿汉式。


作者: 创造命运    时间: 2014-4-17 13:13
以下是我看毕老师视频后自己整理的笔记,或许对你有用。
单例设计模式-----饿汉式、懒汉式  (背也要背下来)
        目的:保证Java虚拟机中一个类的对象始终只有一个,可以节省内存的开销
        单例设计模式要领:
                1.构造方法私有化
                2.对外提供一个公开的静态的获取当前类型对象的构造方法
                3.提供一个当前类型的私有的静态变量
        缺点:单例模式的类型不能被继承,不可能有子类
        饿汉式: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;
                                }
                      }
        饿汉式与懒汉式的区别:懒汉式的特点是实例延迟加载,在有多线程访问时存在安全问题,可以加同步来解决,用双重判断可以解决效率低的问题
        对懒汉式的扩展:               
                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;
                        }
                }


作者: 清风有意    时间: 2014-4-17 13:20
这是我的总结,你看看能否帮到你
1.私有本类构造方法,通过static 方法geiInstance()获取实例对象
2.成员变量;本类引用初始化为null,
3.在需要同步的代码上加锁。(废话)
4.优化同步锁(if(s==null))
  1. class Single
  2. {
  3.         private static Single s=NULL;
  4.         private Single(){}                //单例,不能在本类外newSingled对象。Single s=new Single();
  5.         public static Single getInstance()   //获取实例的方法。即建立对象的方法。
  6.         {
  7.                 if(s==NULL) //这是为了减少判断synchronized,提高效率。
  8.                 {
  9.                         synchronized(Single.class)//找到唯一对象当锁
  10.                         {
  11.                                 if(s==NULL)
  12.                                         s=new Single();
  13.                         }
  14.                 }
  15.                 return s;
  16.         }
  17. }

  18. 懒汉式的特点在于实例的延迟加载

  19. 饿汉式:
  20. class Single
  21. {
  22.   private static final Single s = new Single();
  23.   private Single(){};
  24.   public static Single getInstance()
  25.   {
  26.   return s;
  27.   }
  28. }
复制代码

作者: 491138002    时间: 2014-4-17 13:42
饿汉式:
        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则会导致对对象的访问不是线程安全的
          推荐使用第一种
作者: 也许依然    时间: 2014-4-17 14:15
单例设计模式:解决一个类在内存中只存在一个对象。

想要保证对象唯一
1,为了避免其他程序过多建立该类对象。先禁止其他程序建立该对象
2,还为了让其他程序访问到该对象,只好在本类中自定义一个对象
3,为了方便其他程序对自定义对象的访问,可以对外提供一些访问方式。

这三步怎么用代码体现?
1,将构造函数私有化
2,在类中创建一个本类对象
3,提供一个方法可以获取该对象

对于事物该怎么描述,还怎么描述
当需要该事物的对象保证在内存中唯一时,就将以上的三步加上即可

单例有两种表现形式:

饿汉式:
  1. class Single{
  2.         //构造函数私有化,使外部不能建立对象
  3.         private Single(){}
  4.         //内部建立一个对象,只能由类调用,必须是静态的
  5.         private static Single s = new Single();
  6.         //定义一个获取实例的方法提供给外部
  7.         public static single getInsatnce(){
  8.                 return s;
  9.         }
  10. }
复制代码


懒汉式:
  1. class Single{
  2.         private Single(){}
  3.         private static single s = null;
  4.         public static Single getInsatnce(){
  5.                 if(s==null){
  6.                         synchronized(Single.class){
  7.                                 if(s==null)
  8.                                         s = new Single();
  9.                         }
  10.                 }
  11.                 return s;
  12.         }
  13. }
复制代码


懒汉式有什么特点:
懒汉式的特点在于延迟加载,延迟加载会引发安全问题,在线程切换时可能创建多个对象,使用同步可以解决这个问题,同步中使用的锁是类的字节码,即Single.class,但同步会造成效率降低,所以在获取实例的时候使用了双重判断,使效率提高

在实际应用中要使用饿汉式




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