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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© doevents 中级黑马   /  2013-9-28 10:06  /  1825 人查看  /  7 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 doevents 于 2013-9-28 12:43 编辑

单例模式分为懒汉式和饿汉式,但是他们之间到底有何区别呢,网络上的答案多种多样,不知道哪个是对的,有没有谁能解释下呢?附上代码更好。

7 个回复

倒序浏览
饿汉式:这个在开发的时候是经常用到的,这样不会出现线程的安全情况
懒汉式:这个会出现线程不安全,即使你用锁进行了限制,但是会浪费判断时间,所以效率低
希望对你有帮助!



评分

参与人数 1黑马币 +15 收起 理由
黄炳期 + 15 哈哈!给分!

查看全部评分

回复 使用道具 举报
  1. 饿汉式:一进来就创建对象

  2.         public class Student
  3.         {
  4.                 private Student(){}

  5.                 private static Student s = new Student();

  6.                 public static Student getStudent()
  7.                 {
  8.                         return s;
  9.                 }
  10.         }

  11.         懒汉式:什么时候用,什么时候创建对象

  12.         public class Student
  13.         {
  14.                 private Student(){}

  15.                 private static Student s = null;

  16.                 public synchronized static Student getStudent()
  17.                 {
  18.                         if(s==null)
  19.                         {
  20.                                 s = new Student();
  21.                         }
  22.                         return s;
  23.                 }
  24.         }
复制代码

评分

参与人数 1技术分 +1 收起 理由
黄炳期 + 1 很给力!

查看全部评分

回复 使用道具 举报
public class Singleton {
         private Singleton(){}
         private static Singleton instance = new Singleton();
         public static Singleton getInstance() {
         return instance;
         }
     }
这个就是一个很常用的饿汉式单例模式,只要客户端调用方法:Singleton.getInstance() 就可以使用这个实例,而且是唯一实例.这种使用方式丝毫没有什么限制,任何客户端只要使用该语句就必然可以创建实例.从JAVA语言来说这种方式是最能表现单例模式的了.
同样我们说明懒汉式单例模式仍然使用辛辣面的一个例子:
public class Singleton {
         private Singleton(){}
         private static Singleton instance = null;
         public static synchronized Singleton getInstance() {
         if (instance == null) {
              instance = new Singleton();
         }
         return instance;
         }
     }
这也是一个单例模式,但是他和饿汉式有区别,它在创建时使用了线程标示synchronized ,而且在创建时进行了if (instance == null) {
              instance = new Singleton();
}
的判断.
这有什么用呢?
呵呵,稍微基础好一些的朋友应该一眼就看出来了,它在客户端调用时会有限制,也就是说不能在静态的客户端方法中对该单例类进行实例化.(当然synchronized 是为了if (instance == null) 而使用的)
其实说到底他们之间的区别也并不是很大,只是一个限制的问题,所以在使用该设计模式时从JAVA模式的角度,我是倾向于使用饿汉式.
在方法体中判断if (instance == null)后使用synchronized{},而在synchronized{}中再次对if (instance == null)进行判断,达到双重检测的目的.但是很可惜这个双重检测对JAVA的编译器不成立,因为instance的检测和对他的申明在时间上并没有严格的先后次序,所以编译器可能会先检测再申明而导致崩溃

评分

参与人数 1技术分 +1 收起 理由
黄炳期 + 1 必须要赞

查看全部评分

回复 使用道具 举报
/*
单例设计模式:解决一个类在内存中只存在一个对象

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

使用:
        还想别的类一样该怎么描述怎么描述,该怎么添加成员怎么添加成员
        但是,当需要将该事物的对象保证在内存唯一时,就将上述三步骤加上。
*/

/*
饿汉式
        先初始化对象
        Single类一进入内存,就已经创建好了对象
*/
class  Single
{
        private Single(){}
        private static Single s = new Single();
        public static Single GetInstance()
        {
                return s;
        }
}



/*
懒汉式
        又称延迟加载的单例模式
        对象是方法被调用时,才初始化。
        single类进内存,对象还没有存在,只有调用了GetInstance方法时, 才建立对象

*/
class  Single1
{
        private Single(){}
        private static Single s = null;
        public static Single GetInstance()
        {
                if(s==null)
                {
                        synchronized(Single.class)//线程同步,防止创建多个对象
                        {
                                if(s==null)
                                        s = new Single();
                        }
                }
                return s;
        }
}

/*
建议:开发中使用饿汉式
        饿汉式:这个在开发的时候是经常用到的,这样不会出现线程的安全情况
        懒汉式:这个会出现线程不安全,即使你用锁进行了限制,但是会浪费判断时间,所以效率低
*


希望对你有所帮助

评分

参与人数 1技术分 +1 收起 理由
黄炳期 + 1 赞一个!

查看全部评分

回复 使用道具 举报
饿汉式和懒汉式的区别大家都说的差不多了 这里我就说说懒汉式中两种加锁效率问题吧
第一种是在函数上直接加锁
public static synchronized Singleton getInstance() {
         if (instance == null) {
              instance = new Singleton();
         }
         return instance;
         }
这种加锁方式的弊端就是每次进来都会先判断锁 然后再判断对象是否为null 这样比较耗费时间 效率低

第二种方式是第一次判断锁后 对象被建立 之后会先判断对象是否为空 若为空 后面的锁就不用判断了, 这样效率比第一种高
public static Single GetInstance()
        {
                if(s==null)
                {
                        synchronized(Single.class)
                        {
                                if(s==null)
                                        s = new Single();
                        }
                }
                return s;
        }
开发应用中 一般使用饿汉式。。。
希望对你有所帮助。

评分

参与人数 1技术分 +1 收起 理由
黄炳期 + 1 加油!

查看全部评分

回复 使用道具 举报
如果提问得到解答,请及时编辑帖子,修改主题至“提问结束”。
回复 使用道具 举报
饿汉式:single类一进内存,就已经创建好对象。
class Student
{
private int age;

private Student (){}
private static Student s = new Student();
public static Student getStudeng()
{
  return s;
}

public void setAge(int age)
{
  this.age = age;
}
public int getAge()
{
  return age;
}
}
单例设计模式方法二:懒汉式
对象是方法被调用时,才初始化,也叫做对象的延时加载
single类进内存,对象还没有存在,只有调用getInstance方法时才建立对象。
class Single
{
private static Single s =null;
private Single(){}
public static Single getInstance()
{
  if(s==null)//因为cpu是随机执行程序的所以会有安全隐患。
   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;
    }
   }
  }
}
}

评分

参与人数 1技术分 +1 收起 理由
乔兵 + 1

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马