单例模式的延迟加载

来源:互联网 发布:常见的网络诈骗 编辑:程序博客网 时间:2024/05/21 07:07

单例模式以及延迟加载

发表于2014/10/21 23:56:04  830人阅读

分类: 随写

延迟加载,也叫延迟实例化,延迟初始化等,主要表达的思想就是:把对象的创建延迟到使用的时候创建,而不是对象实例化的时候创建。这种方式避免了性能的浪费。

当创建一个对象的子对象开销比较大时,而且有可能在程序中用不到这个子对象,那么就可以考虑用延迟加载的方式来创建子对象。另外就是当一个程序启动时,需要创建多个对象,但仅有几个对象需要立即使用,那么可以将一些不必要的初始化工作延迟到使用的时候。这样可以提高程序的启动速度。


实例一:

public Class Singleton

{

      private static Singleton instance;

      private Singleton(){ } //私有无参构造


      public static Singleton getInstance(){

    If(instance==null){

       Instance=new Singleton();

    }

    Return instance;

    }

}

构造函数私有,方法静态。

问题:无法保证线程安全,当有多个线程同时访问getInstance的时候,此时若对象为空,就会出现会多个线程同时产生多个Singleton对象。

此时我们可以修改一下上面的代码,如实例二


实例二:

public class Singleton
    {   
       
private static Singleton instance;
       
private static object _lock=new object();

       
private Singleton()
       {

       }

       
public static Singleton GetInstance()
       {
               
if(instance==null)
               {
                      
lock(_lock)
                      {
                             
if(instance==null)
                            {
                                     instance
=new Singleton();
                             }
                      }
               }
               
return instance;
       }
    }

上述代码使用了双重锁方式较好地解决了多线程下的单例模式实现。先看内层的if语句块,使用这个语句块时,先进行加锁操作,保证只有一个线程可以访问该语句块,进而保证只创建了一个实例。再看外层的if语句块,这使得每个线程欲获取实例时不必每次都得加锁,因为只有实例为空时(即需要创建一个实例),才需加锁创建,若果已存在一个实例,就直接返回该实例,节省了性能开销。


实例三:

public class Singleton
          {
                private static Singleton instance = new Singleton();
                private Singleton() {  }

      public static Singleton getInstance()

     {

          return instance;              
     }
}

这个方法保证了在第一次加载的时候实例被初始化,且保证了线程安全。但是为进一步要求,我们想要在使用的时候才才初始化Singleton对象,及延迟加载。那么可以使用实例四方法。


实例四:

public  class Singleton {
    private Singleton() { }

private static class SingletonHolder {
           static Singleton instance = new Singleton();
     }

public static Singleton getInstance() {
            return SingletonHolder.instance;
     }
     public static void main(String [] args)
     {
            Singleton.getInstance();
     }
}

该方法中Singleton 有一个静态内部类SingletonHolder,内部类在外部加载的时候并不会加载,在有在调用getInstance才回加载。另外SingletonHolder类使用Private修饰以确保外部类不能访问。

原创粉丝点击