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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 刘俊佳 中级黑马   /  2012-8-10 10:17  /  1780 人查看  /  7 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

单例设计模式的饿汉式和懒汉式有什么区别?用代码举例详细说明他们之间的区别表现在哪里?

评分

参与人数 1技术分 +1 收起 理由
杨志 + 1

查看全部评分

7 个回复

倒序浏览
本帖最后由 王少岩 于 2012-8-10 10:38 编辑

饿汉式:
  public class Singleton{
      private static Singleton singleton = new Singleton ();
      private Singleton (){}
      public static Singleton getInstance(){
           return singletion;
      }
  }

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

  比较:
  饿汉式是线程安全的,在类创建的同时就已经创建好一个静态的对象供系统使用,以后不在改变。
  懒汉式是延时加载,他是在需要的时候才创建对象,懒汉式如果在创建实例对象时不加上synchronized则会导致对对象的访问不是线程安全的。
  推荐使用第一种  

评分

参与人数 1技术分 +1 收起 理由
杨志 + 1

查看全部评分

回复 使用道具 举报


饿汉式
class Student
        {
                private Student(){} //把构造函数私有化;
                private static Student s = new Student(); //类一加载就直接创建对象;
                public static Student getInstance()
                {
                        return s; //把这个对象返回给调用者;                }
        }

懒汉式

class Teacher
        {
                private Teacher(){}  //私有化构造函数;
                private static Teacher t;  //定义一个指向,指向为空;
                public static Teacher getInstance()
                {
                        if(t==null) //判断此对象是否被调用;                        {
                                t = new Teacher(); / /如果没有调用就创建对象,并指向t;                        }
                        return t;  //如果有对象,就直接返回给调用者;                }
        }

Student类一进内存,就已经创建好了对象。这个称之为饿汉式;

对象是方法被调用时,才初始化,也叫做对象的延时加载。称之为:懒汉式。
Teach类进内存,对象还没有存在,只有调用了getInstance方法时,才建立对象。

评分

参与人数 1技术分 +1 收起 理由
杨志 + 1

查看全部评分

回复 使用道具 举报
饿汉式:先初始化对象。
        Single类一进内存,就已经创建好了对象。
        class Single
        {
                private Single(){}

                private static Single s = new Single();

                public static Single getInstance()
                {
                        return s;
                }
        }
        懒汉式:对象的方法被调用时,才初始化,也叫做对象的延时加载。
        Single类进内存,对象还没用存在,只有调用了getInstance方法时,才建立对象。
        class Single
        {
                private Single(){}

                private static Single s = null;

                public static Single getInstance()
                {
                        if(s==null)
                                s=new Single();
                        return s;
                }
        }
大白话说就是:
饿汉式:因为他饿,所以类一进内存,就已经创建好了对象。
懒汉式:因为他懒,不着急,所以类进内存,对象还没用存在,只有调用方法,才建立对象。
开发一般用饿汉式。

评分

参与人数 1技术分 +1 收起 理由
杨志 + 1

查看全部评分

回复 使用道具 举报
  饿汉式:
  public class Singleton{
  private static Singleton singleton = new Singleton ();   //非延迟加载,类初始化时就建立对象
  private Singleton (){}
  public static Singleton getInstance(){
  return singletion;
  }
  }  
懒汉式:
  public class Singleton{
  private static Singleton singleton = null;    //对象并未创建,延迟加载
  public static Singleton getInstance(){     //当getInstance被调用时才会创建对象
  if(singleton==null){
  singleton = new Singleton();
  }
  return singleton;
  }
  }  

饿汉式相对与懒汉式是线程安全的,类创建时需要的单例已被创建好成一个静态对象了
懒汉式则实现了“延迟加载"也就是在需要的时候再创建对象(被调用getInstance方法的时候),这在缓存里对象比较多的时候效果明显
但懒汉式不是线程安全的,所以需要加入同步,所以上述懒汉式的getInstance方法需要修改为
public static Singleton getInstance(){
  if(singleton!=null){
  return singleton;
  }
  synchronized(Singleton.class){
  if(instance==null){
  singleton = new Singleton();
  }
  }
  return singleton;
  }
一般情况推荐使用饿汉式!
  

评分

参与人数 1技术分 +1 收起 理由
杨志 + 1

查看全部评分

回复 使用道具 举报
谢谢上面各位的解答,问题已经解决
回复 使用道具 举报
王程 中级黑马 2012-8-10 11:11:49
7#
在用到单例时,也推荐使用枚举,每一个枚举对象就是一个单例,如
public enum Single{ single },它与饿汉式都是在类加载时就创建对象,没有延迟加载
回复 使用道具 举报
廖理 中级黑马 2012-8-10 12:06:54
8#
怎样才能保证对象的唯一性呢?
1、        为保证其他程序不过多的建立该类对象,首先禁止其他程序建立对象
2、        为了让其他程序能够访问该类对象,只好在该内中自定义一个对象
3、        为了方便其他程序对自定义对象的访问,可以对外提供一些访问方法
这三部怎样由代码体现呢?
1、        将构造方法私有化
2、        在类中创建一个本类对象
3、        对外提供一个方法可以获取到该对象
// 饿汉式:先初始化 Single一被加载进内存就已经创建了对象

class Single
{
        private static final Single s = new Single();
        private Single(){}
        public static Single getInstance()
        {
                return s;
        }
}



//懒汉式:后初始化Single被加载进内存时还没有创建对象,只有当调用getSingle是才创建对象一般在开发当中多用饿汉式,因为饿汉式的要比懒汉式的安全。
主要是此处
1.if(s == null){
2.          s = new SingleDemo();
        }
存在隐患。当一个程序运行到第一句时,cpu不处理此程序,而去处理另一程序,而另一程序中也,要创建该类,则出现内存中有此类的多个对象。所以要用同步代码块来解决此问题

class Single
{
        private static Single s = null;
        private Single(){}


        public static  Single getInstance()
        {
                if(s==null)
                {
                        synchronized(Single.class)
                        {
                                if(s==null)
                                        //--->A;
                                        s = new Single();
                        }
                }
                return s;
        }
}
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马