懒汉式与饿汉式的区别

J2EE 码拜 8年前 (2016-03-21) 2037次浏览

懒汉式
class Single
{
private static Single s = new Single();
private Single(){}
private static Single getInstance()
{
return s;
}
}
饿汉式
class Single
{
private static Single s =null;
private Single(){}
private static Single getInstance()
{
if(s==null)
s= new Single();
return s;
}
}

解决方案

5

题主最近是在面试吧,可以从字面上去理解,懒汉式:不用的时候不去new这个实例,用到才new,饿汗式是先提前new好实例,
一个是省时间占空间  一个花时间省空间   具体可以到网上找找,

10

所谓“懒汉式”与“饿汉式”的区别,是在与建立单例对象的时间不同。
“懒汉式”是在你真正用到的时候才去建这个单例对象:
例如:有个单例对象
     private static Student student = null;  //不建立对象
     Student getInstance(){
             if(student == null) {        //先判断能否为空
                student = new Student();  //懒汉式做法 
             }
             return student;
          }
“饿汉式”是在不管你用的用不上,一开始就建立这个单例对象:
例如:有个单例对象
      private static Student student = new Student(); //建立对象
      Student getInstance(){
                return student;  //直接返回单例对象
          }

5

第二种这样写不是线程安全的, java 并发编程实战是这么写的
class Single
{
private volatile static Single s =null;  //用volatile保证可见性
private Single(){}
private static Single getInstance()
{
    if(s==null){
        synchronized(this){
            if (s == null)
                s= new Single();
        }
    }

    return s;
}
}

5

明白题主的意思了。在单线程的环境下,单例模式饿汉式和懒汉式没有区别。但是在多线程的环境下,饿汉式没有问题,懒汉式可能会产生初始化多个实例的情况。在多线程的环境下,出错的地方就在if判断这里,没有加线程同步,最高效的保证懒汉式在多线程的环境下,不创建多个对象的代码如下,题主可以参考下:
public class Singleton {
        private static Singleton singleton = null;
private Singleton(){}
public static Singleton getInstance(){
        if(singleton == null){
                synchronized(Singleton.class){
                            if(singleton ==null){
singleton = new Singleton();
}
}
}
return singleton;
}
}

5

通常单例模式在Java语言中,有两种构建方式:
懒汉方式:指全局的单例实例在第一次被使用时构建
饿汉方式:指全局的单例实例在类装载时构建
具体代码,可以参考下面的帖子:
http://bbs.bccn.net/thread-438043-1-1.html

10

楼上各位都回答的差不多了,本人在这里总结一下:
1 区别: 饿汉式:在类加载的时候,就实例化了单例对象,这种方式其实很常用,单例工厂类一般的职责就是负责提供单例,所以它被加载的时候,目的也是为了获取单例,所以从内存使用上来说,并不存在浪费的现象。当然,假如单例工厂类还负责其他的功能,并在类加载的时候不需要初始化单例对象,那么就另说了,其实这种是设计不好的问题。
饿汉式代码:

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

懒汉式:和饿汉式的区别,就是为了节约内存,只有在真正使用单例示例的时候才初始化,并不是在类加载的时候进行初始化。
但是在多线程的情况下,会出现并发问题,假如没有同步控制,就无法保证单例,而饿汉式并不存在这个问题,原因是java虚拟机在类加载的时候已经进行了同步控制,一个类中的静态变量只能初始化一次。
多线程场景下的饿汉式写法:

public class Singleton {
        private static Singleton singleton = null;
private Singleton(){}
public static Singleton getInstance(){
        if(singleton == null){
                synchronized(Singleton.class){
                            if(singleton ==null){
singleton = new Singleton();
}
}
}
return singleton;
}
}

也许有人会问,为什么不在方法上加上同步,还要这么麻烦,其实这是应对高并发访问场景的,假如方法上加同步,那么全部请求都是排队的,而假如先判断,那么在单例实例化之后,访问就不存在同步控制的问题了。


CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明懒汉式与饿汉式的区别
喜欢 (0)
[1034331897@qq.com]
分享 (0)